Compare commits
276 Commits
69760b2adf
...
dbdb2a3274
Author | SHA1 | Date |
---|---|---|
Hendrik Leppkes | dbdb2a3274 | |
Hendrik Leppkes | f32d8ef90f | |
Hendrik Leppkes | b76243085f | |
Hendrik Leppkes | fe4b16c6f7 | |
Hendrik Leppkes | 0f0e68dc33 | |
Hendrik Leppkes | 77b61d2ed9 | |
Hendrik Leppkes | 8eac2d5d93 | |
Hendrik Leppkes | 2e9688b4ff | |
Hendrik Leppkes | 08e2f07124 | |
Hendrik Leppkes | 26858fd0d5 | |
Hendrik Leppkes | 3f4f63d29f | |
Hendrik Leppkes | 53dbf9935f | |
Hendrik Leppkes | b1391a04cc | |
Hendrik Leppkes | 2045f4ada4 | |
Hendrik Leppkes | d6977905ee | |
Hendrik Leppkes | 503d77f1c7 | |
Hendrik Leppkes | 6419dc9fab | |
Hendrik Leppkes | 475c2c3e30 | |
Hendrik Leppkes | de1b375fa6 | |
Hendrik Leppkes | 44913ef34f | |
Hendrik Leppkes | 4c6c2f8726 | |
Hendrik Leppkes | 201b389fe6 | |
Hendrik Leppkes | 66756af9f0 | |
Hendrik Leppkes | 9ab2603dde | |
Hendrik Leppkes | 4a0d8267df | |
Hendrik Leppkes | ad84edf4bc | |
Hendrik Leppkes | 3c798bdfd4 | |
Hendrik Leppkes | 4562c4e9b1 | |
Hendrik Leppkes | b6fd8e399b | |
Hendrik Leppkes | 746a3c89ad | |
Hendrik Leppkes | db71045cc5 | |
Hendrik Leppkes | b9ad463648 | |
Hendrik Leppkes | 4bbe67c894 | |
Hendrik Leppkes | 3545294e80 | |
Hendrik Leppkes | 61d6b18c30 | |
Hendrik Leppkes | ddb1366654 | |
Hendrik Leppkes | 245e560669 | |
Hendrik Leppkes | 869b532875 | |
Hendrik Leppkes | b177e70bea | |
Hendrik Leppkes | 7ef23aff41 | |
Hendrik Leppkes | 3a8f0334ce | |
Hendrik Leppkes | f8f0bef96d | |
Hendrik Leppkes | 0a0c80dcc5 | |
Hendrik Leppkes | 2a8fedcc13 | |
Hendrik Leppkes | 936bb15ef4 | |
Hendrik Leppkes | 977b555a73 | |
Hendrik Leppkes | 4f239e3665 | |
Hendrik Leppkes | cd07cb6289 | |
Hendrik Leppkes | 5c9b2b7692 | |
Hendrik Leppkes | afb0d52014 | |
Hendrik Leppkes | 984165c7d2 | |
Hendrik Leppkes | 47ecb05468 | |
Hendrik Leppkes | 29aa1cc5ba | |
Hendrik Leppkes | e21e89e107 | |
Hendrik Leppkes | 4f2e5c3ecb | |
Hendrik Leppkes | 5747913ccb | |
Hendrik Leppkes | 9839520a6d | |
Hendrik Leppkes | 1da0d139d5 | |
Hendrik Leppkes | 38777dd600 | |
Hendrik Leppkes | c7d9d71dc7 | |
Hendrik Leppkes | 04fb92041c | |
Hendrik Leppkes | 061b216237 | |
Hendrik Leppkes | 85b9bdf565 | |
Hendrik Leppkes | 986f7ce15b | |
Hendrik Leppkes | 4c4ea2c907 | |
Hendrik Leppkes | 308e904d30 | |
Hendrik Leppkes | 85ea63f105 | |
Hendrik Leppkes | ab7ec464a5 | |
Hendrik Leppkes | 07c731dfe1 | |
Hendrik Leppkes | 0be8f348fe | |
Hendrik Leppkes | 97dc135a31 | |
Hendrik Leppkes | 38e9c16e9c | |
Hendrik Leppkes | b1e369e4ab | |
Hendrik Leppkes | 5b650f2db3 | |
Hendrik Leppkes | 0df26f1d56 | |
Hendrik Leppkes | 5c54c741c7 | |
Hendrik Leppkes | 6a60a42b05 | |
Hendrik Leppkes | 6bd25b0f33 | |
Hendrik Leppkes | ccf7fddaf1 | |
Hendrik Leppkes | 4d12d20d45 | |
Hendrik Leppkes | 1a5d39444f | |
onomatopellan | b4772db714 | |
Hendrik Leppkes | 3a77255b72 | |
Hendrik Leppkes | fc528ef7d3 | |
James Almer | 10eb64774f | |
Hendrik Leppkes | d788839dba | |
Hendrik Leppkes | c9056e3d9a | |
Hendrik Leppkes | c449e239bf | |
Hendrik Leppkes | da062205ce | |
Hendrik Leppkes | 81d297fcf7 | |
Hendrik Leppkes | e1da7568ed | |
Hendrik Leppkes | 8625df5f4c | |
Hendrik Leppkes | 2b70ddf527 | |
Hendrik Leppkes | a962a35b9e | |
Hendrik Leppkes | 2083312c86 | |
Hendrik Leppkes | d0a01f17e9 | |
Hendrik Leppkes | b0aa39db76 | |
Hendrik Leppkes | 81b18172da | |
Hendrik Leppkes | 7d7a221ee5 | |
Hendrik Leppkes | eb154ce630 | |
Hendrik Leppkes | d14a1a2485 | |
Carl Eugen Hoyos | 47a231b1cc | |
Hendrik Leppkes | 3ffdbea264 | |
Hendrik Leppkes | 342a342560 | |
Hendrik Leppkes | 2a5913447c | |
Hendrik Leppkes | 31e8a26d6b | |
Hendrik Leppkes | 1fa7be70bc | |
Hendrik Leppkes | 3a03f34d63 | |
Hendrik Leppkes | ff7350ac22 | |
Hendrik Leppkes | 0326fea70b | |
Hendrik Leppkes | 786bde00a6 | |
Hendrik Leppkes | ce3e4f613c | |
Hendrik Leppkes | c7bb5370cf | |
Hendrik Leppkes | 695bbf33f3 | |
Hendrik Leppkes | 0a2a75e085 | |
Hendrik Leppkes | fcf1105b40 | |
Hendrik Leppkes | 17fb405223 | |
Hendrik Leppkes | 7da908791b | |
Hendrik Leppkes | 68b07f53ca | |
Hendrik Leppkes | dcf15661f2 | |
Hendrik Leppkes | 2813208f6d | |
Hendrik Leppkes | 5a4a424c66 | |
Hendrik Leppkes | 5030c62ce3 | |
Hendrik Leppkes | 67bad9bbc0 | |
Hendrik Leppkes | 288b816111 | |
Hendrik Leppkes | 301d733685 | |
Javier Cabezas | a2afa9cb61 | |
Hendrik Leppkes | 436d8cdbd8 | |
Hendrik Leppkes | f801f9f8c2 | |
Hendrik Leppkes | 0a520ddae8 | |
Hendrik Leppkes | 6830266861 | |
Hendrik Leppkes | b9e8e96f4e | |
Hendrik Leppkes | deb07a272a | |
Hendrik Leppkes | a73ab4b2e4 | |
Hendrik Leppkes | 8f98b3586e | |
Hendrik Leppkes | 7c674b2a59 | |
Hendrik Leppkes | e39c5d5c9e | |
Hendrik Leppkes | a33ac8b9ea | |
Hendrik Leppkes | 2f14b484b2 | |
Hendrik Leppkes | 76d6fc987e | |
Hendrik Leppkes | a59883db70 | |
Hendrik Leppkes | ed35fe13f1 | |
Hendrik Leppkes | 84a8cdf791 | |
Hendrik Leppkes | 981d492032 | |
Hendrik Leppkes | 4560e6416f | |
Hendrik Leppkes | a381e5a421 | |
Hendrik Leppkes | a500e80a4a | |
Hendrik Leppkes | 4f2ec9b99d | |
Hendrik Leppkes | b46ea5319c | |
Hendrik Leppkes | f2347d9ad8 | |
Hendrik Leppkes | f95b40648f | |
Hendrik Leppkes | 2d4e0910d2 | |
Hendrik Leppkes | adaf1d0d69 | |
Hendrik Leppkes | f05ebe7750 | |
Hendrik Leppkes | 77b07a84c7 | |
Hendrik Leppkes | 16ff5d966f | |
Hendrik Leppkes | 6133830d4a | |
Hendrik Leppkes | aa29716779 | |
Hendrik Leppkes | 3d94bd5a9f | |
Hendrik Leppkes | 94b22f32b4 | |
Hendrik Leppkes | f02b354572 | |
Hendrik Leppkes | 2332e9c1d5 | |
Hendrik Leppkes | 5310a77ee4 | |
Hendrik Leppkes | d54744910b | |
Hendrik Leppkes | 694af43a77 | |
Hendrik Leppkes | 106568ff4a | |
Hendrik Leppkes | 0a43301e95 | |
Hendrik Leppkes | f536070d4d | |
Hendrik Leppkes | a94b6aa6cf | |
Hendrik Leppkes | 98247d2d82 | |
Hendrik Leppkes | 7e07a38fe8 | |
Hendrik Leppkes | d9955ce11b | |
Hendrik Leppkes | 34a33b5144 | |
Hendrik Leppkes | f36c43440e | |
Hendrik Leppkes | 931da054bb | |
Hendrik Leppkes | 6bbf5c05b1 | |
Hendrik Leppkes | 539b17963b | |
Hendrik Leppkes | e40b1a9214 | |
Hendrik Leppkes | 007f706d5d | |
Cory Fields | c214cdffcb | |
Hendrik Leppkes | 9c2573d91b | |
Hendrik Leppkes | c1d6075033 | |
Hendrik Leppkes | 17ee3fe6a7 | |
Hendrik Leppkes | 4fa8a07c5c | |
Cory Fields | 10a8af3417 | |
Cory Fields | 9d7097b137 | |
Niklas Haas | 5d7f234e7e | |
Niklas Haas | 2e24c12aa1 | |
Niklas Haas | f50382cba6 | |
Niklas Haas | 1535d33818 | |
Niklas Haas | a9023377b2 | |
Niklas Haas | ea147f3b50 | |
Niklas Haas | 1539efaacb | |
Niklas Haas | 511f297680 | |
Niklas Haas | ad7f059180 | |
Niklas Haas | 6963033590 | |
Niklas Haas | 25cd0e0913 | |
Niklas Haas | a08f358769 | |
Niklas Haas | 35d2960dcd | |
Jun Zhao | bfbf0f4e82 | |
Michael Niedermayer | 57f252b2d1 | |
Anton Khirnov | e99594812c | |
Leo Izen | 83ed18a3ca | |
Wenbin Chen | f34000541a | |
Stefano Sabatini | 7852bf02b0 | |
Stefano Sabatini | 25248c9d75 | |
Stefano Sabatini | 5c60be3ab6 | |
Stefano Sabatini | 3733aa7b17 | |
Matthieu Bouron | ad227a41d4 | |
Matthieu Bouron | b1a683a2fd | |
Matthieu Bouron | dab4124350 | |
Matthieu Bouron | 70ba15d2cf | |
Matthieu Bouron | 6567516a5e | |
Matthieu Bouron | f17e18d292 | |
Andreas Rheinhardt | 073251316e | |
Andreas Rheinhardt | 37f0dbbc39 | |
Andreas Rheinhardt | 2ccb45511f | |
Andreas Rheinhardt | a24bccc238 | |
Andreas Rheinhardt | 03b04eef72 | |
Andreas Rheinhardt | f4167842c1 | |
Andreas Rheinhardt | c6bc2d4fea | |
Andreas Rheinhardt | a48e839a22 | |
Andreas Rheinhardt | 789c5b03db | |
Andreas Rheinhardt | 233e13f285 | |
Andreas Rheinhardt | b8124fe35e | |
Andreas Rheinhardt | eb3ee7f141 | |
Andreas Rheinhardt | d11b5e6096 | |
Andreas Rheinhardt | b7bec5d3c9 | |
Andreas Rheinhardt | 26398da8f3 | |
Andreas Rheinhardt | b9fcc135c5 | |
Andreas Rheinhardt | 244db71037 | |
Andreas Rheinhardt | c77164390b | |
Andreas Rheinhardt | 6ecc2f0f6f | |
Andreas Rheinhardt | 3fd047ee30 | |
Andreas Rheinhardt | c89f6ae689 | |
Niklas Haas | f04a2ba302 | |
Niklas Haas | d5648a806f | |
Zhao Zhili | 4869171aa9 | |
Zhao Zhili | 5229778440 | |
Zhao Zhili | c775163a8c | |
Andreas Rheinhardt | ee736ff80e | |
James Almer | 535b1a93f5 | |
James Almer | 456c8ebe7c | |
James Almer | 97d2990ea6 | |
James Almer | e04c638f5f | |
James Almer | 5ff0eb34d2 | |
James Almer | 6c2ff982dc | |
Jan Ekström | d7d2213a6b | |
Jan Ekström | 471c0a34c1 | |
Jan Ekström | f4b89b6e54 | |
Jan Ekström | 8f4b173029 | |
Jan Ekström | 0d36844ddf | |
Jan Ekström | d9ade14c5c | |
Jan Ekström | f287a285d9 | |
Jan Ekström | 3c52f73e25 | |
Jan Ekström | 53335f6cf4 | |
Jan Ekström | d2bb22f6d5 | |
Jan Ekström | 28783896dc | |
Jan Ekström | 919c9cdbe6 | |
Jan Ekström | d5104b3401 | |
Frank Plowman | dfcf5f828d | |
Andreas Rheinhardt | 0b7d4fccce | |
Andreas Rheinhardt | cd8cc3d1b3 | |
Andreas Rheinhardt | 6a9ddfcd96 | |
Andreas Rheinhardt | a7ad5d4d10 | |
Mark Thompson | 7f4b8d2f5e | |
Marton Balint | 7251f90972 | |
Stefano Sabatini | 0cd13ad674 | |
Stefano Sabatini | f7d560e919 | |
Stefano Sabatini | 9afd9bb5c5 | |
Marth64 | 0b342a2f15 | |
James Almer | 53dd31497b | |
James Almer | 61519cc654 | |
James Almer | a1f714d197 | |
James Almer | 4ca5d45193 | |
Wenbin Chen | f4e0664fd1 |
|
@ -0,0 +1,3 @@
|
||||||
|
IndentWidth: 4
|
||||||
|
UseTab: Never
|
||||||
|
DisableFormat: true
|
|
@ -35,6 +35,8 @@ version <next>:
|
||||||
- AEA muxer
|
- AEA muxer
|
||||||
- ffmpeg CLI loopback decoders
|
- ffmpeg CLI loopback decoders
|
||||||
- Support PacketTypeMetadata of PacketType in enhanced flv format
|
- Support PacketTypeMetadata of PacketType in enhanced flv format
|
||||||
|
- ffplay with hwaccel decoding support (depends on vulkan renderer via libplacebo)
|
||||||
|
- dnn filter libtorch backend
|
||||||
|
|
||||||
|
|
||||||
version 6.1:
|
version 6.1:
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// File: DXVA.h
|
||||||
|
//
|
||||||
|
// Desc: DirectX Video Acceleration header file.
|
||||||
|
//
|
||||||
|
// Copyright (c) 1999 - 2002, Microsoft Corporation. All rights reserved.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef _DIRECTX_AV1_VA_
|
||||||
|
#define _DIRECTX_AV1_VA_
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
/* AV1 picture entry data structure */
|
||||||
|
typedef struct _DXVA_PicEntry_AV1 {
|
||||||
|
|
||||||
|
UINT width;
|
||||||
|
UINT height;
|
||||||
|
|
||||||
|
// Global motion parameters
|
||||||
|
INT wmmat[6];
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR wminvalid : 1;
|
||||||
|
UCHAR wmtype : 2;
|
||||||
|
UCHAR Reserved : 5;
|
||||||
|
};
|
||||||
|
UCHAR GlobalMotionFlags;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
|
||||||
|
UCHAR Index;
|
||||||
|
UINT16 Reserved16Bits;
|
||||||
|
|
||||||
|
} DXVA_PicEntry_AV1, *LPDXVA_PicEntry_AV1;
|
||||||
|
|
||||||
|
/* AV1 picture parameters structure */
|
||||||
|
typedef struct _DXVA_PicParams_AV1 {
|
||||||
|
UINT width;
|
||||||
|
UINT height;
|
||||||
|
|
||||||
|
UINT max_width;
|
||||||
|
UINT max_height;
|
||||||
|
|
||||||
|
UCHAR CurrPicTextureIndex;
|
||||||
|
UCHAR superres_denom;
|
||||||
|
UCHAR bitdepth;
|
||||||
|
UCHAR seq_profile;
|
||||||
|
|
||||||
|
// Tiles:
|
||||||
|
struct {
|
||||||
|
UCHAR cols;
|
||||||
|
UCHAR rows;
|
||||||
|
USHORT context_update_id;
|
||||||
|
USHORT widths[64];
|
||||||
|
USHORT heights[64];
|
||||||
|
} tiles;
|
||||||
|
|
||||||
|
// Coding Tools
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UINT use_128x128_superblock : 1;
|
||||||
|
UINT intra_edge_filter : 1;
|
||||||
|
UINT interintra_compound : 1;
|
||||||
|
UINT masked_compound : 1;
|
||||||
|
UINT warped_motion : 1;
|
||||||
|
UINT dual_filter : 1;
|
||||||
|
UINT jnt_comp : 1;
|
||||||
|
UINT screen_content_tools : 1;
|
||||||
|
UINT integer_mv : 1;
|
||||||
|
UINT cdef : 1;
|
||||||
|
UINT restoration : 1;
|
||||||
|
UINT film_grain : 1;
|
||||||
|
UINT intrabc : 1;
|
||||||
|
UINT high_precision_mv : 1;
|
||||||
|
UINT switchable_motion_mode : 1;
|
||||||
|
UINT filter_intra : 1;
|
||||||
|
UINT disable_frame_end_update_cdf : 1;
|
||||||
|
UINT disable_cdf_update : 1;
|
||||||
|
UINT reference_mode : 1;
|
||||||
|
UINT skip_mode : 1;
|
||||||
|
UINT reduced_tx_set : 1;
|
||||||
|
UINT superres : 1;
|
||||||
|
UINT tx_mode : 2;
|
||||||
|
UINT use_ref_frame_mvs : 1;
|
||||||
|
UINT enable_ref_frame_mvs : 1;
|
||||||
|
UINT reference_frame_update : 1;
|
||||||
|
UINT Reserved : 5;
|
||||||
|
};
|
||||||
|
UINT32 CodingParamToolFlags;
|
||||||
|
} coding;
|
||||||
|
|
||||||
|
// Format & Picture Info flags
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR frame_type : 2;
|
||||||
|
UCHAR show_frame : 1;
|
||||||
|
UCHAR showable_frame : 1;
|
||||||
|
UCHAR subsampling_x : 1;
|
||||||
|
UCHAR subsampling_y : 1;
|
||||||
|
UCHAR mono_chrome : 1;
|
||||||
|
UCHAR Reserved : 1;
|
||||||
|
};
|
||||||
|
UCHAR FormatAndPictureInfoFlags;
|
||||||
|
} format;
|
||||||
|
|
||||||
|
// References
|
||||||
|
UCHAR primary_ref_frame;
|
||||||
|
UCHAR order_hint;
|
||||||
|
UCHAR order_hint_bits;
|
||||||
|
|
||||||
|
DXVA_PicEntry_AV1 frame_refs[7];
|
||||||
|
UCHAR RefFrameMapTextureIndex[8];
|
||||||
|
|
||||||
|
// Loop filter parameters
|
||||||
|
struct {
|
||||||
|
UCHAR filter_level[2];
|
||||||
|
UCHAR filter_level_u;
|
||||||
|
UCHAR filter_level_v;
|
||||||
|
|
||||||
|
UCHAR sharpness_level;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR mode_ref_delta_enabled : 1;
|
||||||
|
UCHAR mode_ref_delta_update : 1;
|
||||||
|
UCHAR delta_lf_multi : 1;
|
||||||
|
UCHAR delta_lf_present : 1;
|
||||||
|
UCHAR Reserved : 4;
|
||||||
|
};
|
||||||
|
UCHAR ControlFlags;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
CHAR ref_deltas[8];
|
||||||
|
CHAR mode_deltas[2];
|
||||||
|
UCHAR delta_lf_res;
|
||||||
|
UCHAR frame_restoration_type[3];
|
||||||
|
USHORT log2_restoration_unit_size[3];
|
||||||
|
UINT16 Reserved16Bits;
|
||||||
|
} loop_filter;
|
||||||
|
|
||||||
|
// Quantization
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR delta_q_present : 1;
|
||||||
|
UCHAR delta_q_res : 2;
|
||||||
|
UCHAR Reserved : 5;
|
||||||
|
};
|
||||||
|
UCHAR ControlFlags;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
|
||||||
|
UCHAR base_qindex;
|
||||||
|
CHAR y_dc_delta_q;
|
||||||
|
CHAR u_dc_delta_q;
|
||||||
|
CHAR v_dc_delta_q;
|
||||||
|
CHAR u_ac_delta_q;
|
||||||
|
CHAR v_ac_delta_q;
|
||||||
|
// using_qmatrix:
|
||||||
|
UCHAR qm_y;
|
||||||
|
UCHAR qm_u;
|
||||||
|
UCHAR qm_v;
|
||||||
|
UINT16 Reserved16Bits;
|
||||||
|
} quantization;
|
||||||
|
|
||||||
|
// Cdef parameters
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR damping : 2;
|
||||||
|
UCHAR bits : 2;
|
||||||
|
UCHAR Reserved : 4;
|
||||||
|
};
|
||||||
|
UCHAR ControlFlags;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR primary : 6;
|
||||||
|
UCHAR secondary : 2;
|
||||||
|
};
|
||||||
|
UCHAR combined;
|
||||||
|
} y_strengths[8];
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR primary : 6;
|
||||||
|
UCHAR secondary : 2;
|
||||||
|
};
|
||||||
|
UCHAR combined;
|
||||||
|
} uv_strengths[8];
|
||||||
|
|
||||||
|
} cdef;
|
||||||
|
|
||||||
|
UCHAR interp_filter;
|
||||||
|
|
||||||
|
// Segmentation
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR enabled : 1;
|
||||||
|
UCHAR update_map : 1;
|
||||||
|
UCHAR update_data : 1;
|
||||||
|
UCHAR temporal_update : 1;
|
||||||
|
UCHAR Reserved : 4;
|
||||||
|
};
|
||||||
|
UCHAR ControlFlags;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
UCHAR Reserved24Bits[3];
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR alt_q : 1;
|
||||||
|
UCHAR alt_lf_y_v : 1;
|
||||||
|
UCHAR alt_lf_y_h : 1;
|
||||||
|
UCHAR alt_lf_u : 1;
|
||||||
|
UCHAR alt_lf_v : 1;
|
||||||
|
UCHAR ref_frame : 1;
|
||||||
|
UCHAR skip : 1;
|
||||||
|
UCHAR globalmv : 1;
|
||||||
|
};
|
||||||
|
UCHAR mask;
|
||||||
|
} feature_mask[8];
|
||||||
|
|
||||||
|
SHORT feature_data[8][8];
|
||||||
|
|
||||||
|
} segmentation;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
USHORT apply_grain : 1;
|
||||||
|
USHORT scaling_shift_minus8 : 2;
|
||||||
|
USHORT chroma_scaling_from_luma : 1;
|
||||||
|
USHORT ar_coeff_lag : 2;
|
||||||
|
USHORT ar_coeff_shift_minus6 : 2;
|
||||||
|
USHORT grain_scale_shift : 2;
|
||||||
|
USHORT overlap_flag : 1;
|
||||||
|
USHORT clip_to_restricted_range : 1;
|
||||||
|
USHORT matrix_coeff_is_identity : 1;
|
||||||
|
USHORT Reserved : 3;
|
||||||
|
};
|
||||||
|
USHORT ControlFlags;
|
||||||
|
} DUMMYUNIONNAME;
|
||||||
|
|
||||||
|
USHORT grain_seed;
|
||||||
|
UCHAR scaling_points_y[14][2];
|
||||||
|
UCHAR num_y_points;
|
||||||
|
UCHAR scaling_points_cb[10][2];
|
||||||
|
UCHAR num_cb_points;
|
||||||
|
UCHAR scaling_points_cr[10][2];
|
||||||
|
UCHAR num_cr_points;
|
||||||
|
UCHAR ar_coeffs_y[24];
|
||||||
|
UCHAR ar_coeffs_cb[25];
|
||||||
|
UCHAR ar_coeffs_cr[25];
|
||||||
|
UCHAR cb_mult;
|
||||||
|
UCHAR cb_luma_mult;
|
||||||
|
UCHAR cr_mult;
|
||||||
|
UCHAR cr_luma_mult;
|
||||||
|
UCHAR Reserved8Bits;
|
||||||
|
SHORT cb_offset;
|
||||||
|
SHORT cr_offset;
|
||||||
|
} film_grain;
|
||||||
|
|
||||||
|
UINT Reserved32Bits;
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
} DXVA_PicParams_AV1, *LPDXVA_PicParams_AV1;
|
||||||
|
|
||||||
|
/* AV1 tile structure */
|
||||||
|
typedef struct _DXVA_Tile_AV1 {
|
||||||
|
UINT DataOffset;
|
||||||
|
UINT DataSize;
|
||||||
|
USHORT row;
|
||||||
|
USHORT column;
|
||||||
|
UINT16 Reserved16Bits;
|
||||||
|
UCHAR anchor_frame;
|
||||||
|
UCHAR Reserved8Bits;
|
||||||
|
} DXVA_Tile_AV1, *LPDXVA_Tile_AV1;
|
||||||
|
|
||||||
|
/* AV1 status reporting data structure */
|
||||||
|
typedef struct _DXVA_Status_AV1 {
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
DXVA_PicEntry_AV1 CurrPic;
|
||||||
|
UCHAR BufType;
|
||||||
|
UCHAR Status;
|
||||||
|
UCHAR Reserved8Bits;
|
||||||
|
USHORT NumMbsAffected;
|
||||||
|
} DXVA_Status_AV1, *LPDXVA_Status_AV1;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#endif // _DIRECTX_AV1_VA_
|
|
@ -0,0 +1,150 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 1999 - 2002, Microsoft Corporation. All rights reserved.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __DIRECTX_VA_HEVC__
|
||||||
|
#define __DIRECTX_VA_HEVC__
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
/* HEVC Picture Entry structure */
|
||||||
|
typedef struct _DXVA_PicEntry_HEVC
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UCHAR Index7Bits : 7;
|
||||||
|
UCHAR AssociatedFlag : 1;
|
||||||
|
};
|
||||||
|
UCHAR bPicEntry;
|
||||||
|
};
|
||||||
|
} DXVA_PicEntry_HEVC, *LPDXVA_PicEntry_HEVC;
|
||||||
|
|
||||||
|
/* HEVC Picture Parameter structure */
|
||||||
|
typedef struct _DXVA_PicParams_HEVC {
|
||||||
|
USHORT PicWidthInMinCbsY;
|
||||||
|
USHORT PicHeightInMinCbsY;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
USHORT chroma_format_idc : 2;
|
||||||
|
USHORT separate_colour_plane_flag : 1;
|
||||||
|
USHORT bit_depth_luma_minus8 : 3;
|
||||||
|
USHORT bit_depth_chroma_minus8 : 3;
|
||||||
|
USHORT log2_max_pic_order_cnt_lsb_minus4 : 4;
|
||||||
|
USHORT NoPicReorderingFlag : 1;
|
||||||
|
USHORT NoBiPredFlag : 1;
|
||||||
|
USHORT ReservedBits1 : 1;
|
||||||
|
};
|
||||||
|
USHORT wFormatAndSequenceInfoFlags;
|
||||||
|
};
|
||||||
|
DXVA_PicEntry_HEVC CurrPic;
|
||||||
|
UCHAR sps_max_dec_pic_buffering_minus1;
|
||||||
|
UCHAR log2_min_luma_coding_block_size_minus3;
|
||||||
|
UCHAR log2_diff_max_min_luma_coding_block_size;
|
||||||
|
UCHAR log2_min_transform_block_size_minus2;
|
||||||
|
UCHAR log2_diff_max_min_transform_block_size;
|
||||||
|
UCHAR max_transform_hierarchy_depth_inter;
|
||||||
|
UCHAR max_transform_hierarchy_depth_intra;
|
||||||
|
UCHAR num_short_term_ref_pic_sets;
|
||||||
|
UCHAR num_long_term_ref_pics_sps;
|
||||||
|
UCHAR num_ref_idx_l0_default_active_minus1;
|
||||||
|
UCHAR num_ref_idx_l1_default_active_minus1;
|
||||||
|
CHAR init_qp_minus26;
|
||||||
|
UCHAR ucNumDeltaPocsOfRefRpsIdx;
|
||||||
|
USHORT wNumBitsForShortTermRPSInSlice;
|
||||||
|
USHORT ReservedBits2;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UINT32 scaling_list_enabled_flag : 1;
|
||||||
|
UINT32 amp_enabled_flag : 1;
|
||||||
|
UINT32 sample_adaptive_offset_enabled_flag : 1;
|
||||||
|
UINT32 pcm_enabled_flag : 1;
|
||||||
|
UINT32 pcm_sample_bit_depth_luma_minus1 : 4;
|
||||||
|
UINT32 pcm_sample_bit_depth_chroma_minus1 : 4;
|
||||||
|
UINT32 log2_min_pcm_luma_coding_block_size_minus3 : 2;
|
||||||
|
UINT32 log2_diff_max_min_pcm_luma_coding_block_size : 2;
|
||||||
|
UINT32 pcm_loop_filter_disabled_flag : 1;
|
||||||
|
UINT32 long_term_ref_pics_present_flag : 1;
|
||||||
|
UINT32 sps_temporal_mvp_enabled_flag : 1;
|
||||||
|
UINT32 strong_intra_smoothing_enabled_flag : 1;
|
||||||
|
UINT32 dependent_slice_segments_enabled_flag : 1;
|
||||||
|
UINT32 output_flag_present_flag : 1;
|
||||||
|
UINT32 num_extra_slice_header_bits : 3;
|
||||||
|
UINT32 sign_data_hiding_enabled_flag : 1;
|
||||||
|
UINT32 cabac_init_present_flag : 1;
|
||||||
|
UINT32 ReservedBits3 : 5;
|
||||||
|
};
|
||||||
|
UINT32 dwCodingParamToolFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UINT32 constrained_intra_pred_flag : 1;
|
||||||
|
UINT32 transform_skip_enabled_flag : 1;
|
||||||
|
UINT32 cu_qp_delta_enabled_flag : 1;
|
||||||
|
UINT32 pps_slice_chroma_qp_offsets_present_flag : 1;
|
||||||
|
UINT32 weighted_pred_flag : 1;
|
||||||
|
UINT32 weighted_bipred_flag : 1;
|
||||||
|
UINT32 transquant_bypass_enabled_flag : 1;
|
||||||
|
UINT32 tiles_enabled_flag : 1;
|
||||||
|
UINT32 entropy_coding_sync_enabled_flag : 1;
|
||||||
|
UINT32 uniform_spacing_flag : 1;
|
||||||
|
UINT32 loop_filter_across_tiles_enabled_flag : 1;
|
||||||
|
UINT32 pps_loop_filter_across_slices_enabled_flag : 1;
|
||||||
|
UINT32 deblocking_filter_override_enabled_flag : 1;
|
||||||
|
UINT32 pps_deblocking_filter_disabled_flag : 1;
|
||||||
|
UINT32 lists_modification_present_flag : 1;
|
||||||
|
UINT32 slice_segment_header_extension_present_flag : 1;
|
||||||
|
UINT32 IrapPicFlag : 1;
|
||||||
|
UINT32 IdrPicFlag : 1;
|
||||||
|
UINT32 IntraPicFlag : 1;
|
||||||
|
UINT32 ReservedBits4 : 13;
|
||||||
|
};
|
||||||
|
UINT32 dwCodingSettingPicturePropertyFlags;
|
||||||
|
};
|
||||||
|
CHAR pps_cb_qp_offset;
|
||||||
|
CHAR pps_cr_qp_offset;
|
||||||
|
UCHAR num_tile_columns_minus1;
|
||||||
|
UCHAR num_tile_rows_minus1;
|
||||||
|
USHORT column_width_minus1[19];
|
||||||
|
USHORT row_height_minus1[21];
|
||||||
|
UCHAR diff_cu_qp_delta_depth;
|
||||||
|
CHAR pps_beta_offset_div2;
|
||||||
|
CHAR pps_tc_offset_div2;
|
||||||
|
UCHAR log2_parallel_merge_level_minus2;
|
||||||
|
INT CurrPicOrderCntVal;
|
||||||
|
DXVA_PicEntry_HEVC RefPicList[15];
|
||||||
|
UCHAR ReservedBits5;
|
||||||
|
INT PicOrderCntValList[15];
|
||||||
|
UCHAR RefPicSetStCurrBefore[8];
|
||||||
|
UCHAR RefPicSetStCurrAfter[8];
|
||||||
|
UCHAR RefPicSetLtCurr[8];
|
||||||
|
USHORT ReservedBits6;
|
||||||
|
USHORT ReservedBits7;
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
} DXVA_PicParams_HEVC, *LPDXVA_PicParams_HEVC;
|
||||||
|
|
||||||
|
/* HEVC Quantizatiuon Matrix structure */
|
||||||
|
typedef struct _DXVA_Qmatrix_HEVC
|
||||||
|
{
|
||||||
|
UCHAR ucScalingLists0[6][16];
|
||||||
|
UCHAR ucScalingLists1[6][64];
|
||||||
|
UCHAR ucScalingLists2[6][64];
|
||||||
|
UCHAR ucScalingLists3[2][64];
|
||||||
|
UCHAR ucScalingListDCCoefSizeID2[6];
|
||||||
|
UCHAR ucScalingListDCCoefSizeID3[2];
|
||||||
|
} DXVA_Qmatrix_HEVC, *LPDXVA_Qmatrix_HEVC;
|
||||||
|
|
||||||
|
|
||||||
|
/* HEVC Slice Control Structure */
|
||||||
|
typedef struct _DXVA_Slice_HEVC_Short
|
||||||
|
{
|
||||||
|
UINT BSNALunitDataLocation;
|
||||||
|
UINT SliceBytesInBuffer;
|
||||||
|
USHORT wBadSliceChopping;
|
||||||
|
} DXVA_Slice_HEVC_Short, *LPDXVA_Slice_HEVC_Short;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif
|
|
@ -0,0 +1,185 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 1999 - 2002, Microsoft Corporation. All rights reserved.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __DIRECTX_VA_VPX__
|
||||||
|
#define __DIRECTX_VA_VPX__
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
/* VPx picture entry data structure */
|
||||||
|
typedef struct _DXVA_PicEntry_VPx {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR Index7Bits : 7;
|
||||||
|
UCHAR AssociatedFlag : 1;
|
||||||
|
};
|
||||||
|
UCHAR bPicEntry;
|
||||||
|
};
|
||||||
|
} DXVA_PicEntry_VPx, *LPDXVA_PicEntry_VPx;
|
||||||
|
|
||||||
|
/* VP9 segmentation structure */
|
||||||
|
typedef struct _segmentation_VP9 {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR enabled : 1;
|
||||||
|
UCHAR update_map : 1;
|
||||||
|
UCHAR temporal_update : 1;
|
||||||
|
UCHAR abs_delta : 1;
|
||||||
|
UCHAR ReservedSegmentFlags4Bits : 4;
|
||||||
|
};
|
||||||
|
UCHAR wSegmentInfoFlags;
|
||||||
|
};
|
||||||
|
UCHAR tree_probs[7];
|
||||||
|
UCHAR pred_probs[3];
|
||||||
|
SHORT feature_data[8][4];
|
||||||
|
UCHAR feature_mask[8];
|
||||||
|
} DXVA_segmentation_VP9;
|
||||||
|
|
||||||
|
/* VP9 picture parameters structure */
|
||||||
|
typedef struct _DXVA_PicParams_VP9 {
|
||||||
|
DXVA_PicEntry_VPx CurrPic;
|
||||||
|
UCHAR profile;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
USHORT frame_type : 1;
|
||||||
|
USHORT show_frame : 1;
|
||||||
|
USHORT error_resilient_mode : 1;
|
||||||
|
USHORT subsampling_x : 1;
|
||||||
|
USHORT subsampling_y : 1;
|
||||||
|
USHORT extra_plane : 1;
|
||||||
|
USHORT refresh_frame_context : 1;
|
||||||
|
USHORT frame_parallel_decoding_mode : 1;
|
||||||
|
USHORT intra_only : 1;
|
||||||
|
USHORT frame_context_idx : 2;
|
||||||
|
USHORT reset_frame_context : 2;
|
||||||
|
USHORT allow_high_precision_mv : 1;
|
||||||
|
USHORT ReservedFormatInfo2Bits : 2;
|
||||||
|
};
|
||||||
|
USHORT wFormatAndPictureInfoFlags;
|
||||||
|
};
|
||||||
|
UINT width;
|
||||||
|
UINT height;
|
||||||
|
UCHAR BitDepthMinus8Luma;
|
||||||
|
UCHAR BitDepthMinus8Chroma;
|
||||||
|
UCHAR interp_filter;
|
||||||
|
UCHAR Reserved8Bits;
|
||||||
|
DXVA_PicEntry_VPx ref_frame_map[8];
|
||||||
|
UINT ref_frame_coded_width[8];
|
||||||
|
UINT ref_frame_coded_height[8];
|
||||||
|
DXVA_PicEntry_VPx frame_refs[3];
|
||||||
|
CHAR ref_frame_sign_bias[4];
|
||||||
|
CHAR filter_level;
|
||||||
|
CHAR sharpness_level;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR mode_ref_delta_enabled : 1;
|
||||||
|
UCHAR mode_ref_delta_update : 1;
|
||||||
|
UCHAR use_prev_in_find_mv_refs : 1;
|
||||||
|
UCHAR ReservedControlInfo5Bits : 5;
|
||||||
|
};
|
||||||
|
UCHAR wControlInfoFlags;
|
||||||
|
};
|
||||||
|
CHAR ref_deltas[4];
|
||||||
|
CHAR mode_deltas[2];
|
||||||
|
SHORT base_qindex;
|
||||||
|
CHAR y_dc_delta_q;
|
||||||
|
CHAR uv_dc_delta_q;
|
||||||
|
CHAR uv_ac_delta_q;
|
||||||
|
DXVA_segmentation_VP9 stVP9Segments;
|
||||||
|
UCHAR log2_tile_cols;
|
||||||
|
UCHAR log2_tile_rows;
|
||||||
|
USHORT uncompressed_header_size_byte_aligned;
|
||||||
|
USHORT first_partition_size;
|
||||||
|
USHORT Reserved16Bits;
|
||||||
|
UINT Reserved32Bits;
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
} DXVA_PicParams_VP9, *LPDXVA_PicParams_VP9;
|
||||||
|
|
||||||
|
/* VP8 segmentation structure */
|
||||||
|
typedef struct _segmentation_VP8 {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR segmentation_enabled : 1;
|
||||||
|
UCHAR update_mb_segmentation_map : 1;
|
||||||
|
UCHAR update_mb_segmentation_data : 1;
|
||||||
|
UCHAR mb_segement_abs_delta : 1;
|
||||||
|
UCHAR ReservedSegmentFlags4Bits : 4;
|
||||||
|
};
|
||||||
|
UCHAR wSegmentFlags;
|
||||||
|
};
|
||||||
|
CHAR segment_feature_data[2][4];
|
||||||
|
UCHAR mb_segment_tree_probs[3];
|
||||||
|
} DXVA_segmentation_VP8;
|
||||||
|
|
||||||
|
/* VP8 picture parameters structure */
|
||||||
|
typedef struct _DXVA_PicParams_VP8 {
|
||||||
|
UINT first_part_size;
|
||||||
|
UINT width;
|
||||||
|
UINT height;
|
||||||
|
DXVA_PicEntry_VPx CurrPic;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR frame_type : 1;
|
||||||
|
UCHAR version : 3;
|
||||||
|
UCHAR show_frame : 1;
|
||||||
|
UCHAR clamp_type : 1;
|
||||||
|
UCHAR ReservedFrameTag3Bits : 2;
|
||||||
|
};
|
||||||
|
UCHAR wFrameTagFlags;
|
||||||
|
};
|
||||||
|
DXVA_segmentation_VP8 stVP8Segments;
|
||||||
|
UCHAR filter_type;
|
||||||
|
UCHAR filter_level;
|
||||||
|
UCHAR sharpness_level;
|
||||||
|
UCHAR mode_ref_lf_delta_enabled;
|
||||||
|
UCHAR mode_ref_lf_delta_update;
|
||||||
|
CHAR ref_lf_deltas[4];
|
||||||
|
CHAR mode_lf_deltas[4];
|
||||||
|
UCHAR log2_nbr_of_dct_partitions;
|
||||||
|
UCHAR base_qindex;
|
||||||
|
CHAR y1dc_delta_q;
|
||||||
|
CHAR y2dc_delta_q;
|
||||||
|
CHAR y2ac_delta_q;
|
||||||
|
CHAR uvdc_delta_q;
|
||||||
|
CHAR uvac_delta_q;
|
||||||
|
DXVA_PicEntry_VPx alt_fb_idx;
|
||||||
|
DXVA_PicEntry_VPx gld_fb_idx;
|
||||||
|
DXVA_PicEntry_VPx lst_fb_idx;
|
||||||
|
UCHAR ref_frame_sign_bias_golden;
|
||||||
|
UCHAR ref_frame_sign_bias_altref;
|
||||||
|
UCHAR refresh_entropy_probs;
|
||||||
|
UCHAR vp8_coef_update_probs[4][8][3][11];
|
||||||
|
UCHAR mb_no_coeff_skip;
|
||||||
|
UCHAR prob_skip_false;
|
||||||
|
UCHAR prob_intra;
|
||||||
|
UCHAR prob_last;
|
||||||
|
UCHAR prob_golden;
|
||||||
|
UCHAR intra_16x16_prob[4];
|
||||||
|
UCHAR intra_chroma_prob[3];
|
||||||
|
UCHAR vp8_mv_update_probs[2][19];
|
||||||
|
USHORT ReservedBits1;
|
||||||
|
USHORT ReservedBits2;
|
||||||
|
USHORT ReservedBits3;
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
} DXVA_PicParams_VP8, *LPDXVA_PicParams_VP8;
|
||||||
|
|
||||||
|
/* VPx slice control data structure - short form */
|
||||||
|
typedef struct _DXVA_Slice_VPx_Short {
|
||||||
|
UINT BSNALunitDataLocation;
|
||||||
|
UINT SliceBytesInBuffer;
|
||||||
|
USHORT wBadSliceChopping;
|
||||||
|
} DXVA_Slice_VPx_Short, *LPDXVA_Slice_VPx_Short;
|
||||||
|
|
||||||
|
/* VPx status reporting data structure */
|
||||||
|
typedef struct _DXVA_Status_VPx {
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
DXVA_PicEntry_VPx CurrPic;
|
||||||
|
UCHAR bBufType;
|
||||||
|
UCHAR bStatus;
|
||||||
|
UCHAR bReserved8Bits;
|
||||||
|
USHORT wNumMbsAffected;
|
||||||
|
} DXVA_Status_VPx, *LPDXVA_Status_VPx;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif
|
|
@ -281,6 +281,7 @@ External library support:
|
||||||
--enable-libtheora enable Theora encoding via libtheora [no]
|
--enable-libtheora enable Theora encoding via libtheora [no]
|
||||||
--enable-libtls enable LibreSSL (via libtls), needed for https support
|
--enable-libtls enable LibreSSL (via libtls), needed for https support
|
||||||
if openssl, gnutls or mbedtls is not used [no]
|
if openssl, gnutls or mbedtls is not used [no]
|
||||||
|
--enable-libtorch enable Torch as one DNN backend [no]
|
||||||
--enable-libtwolame enable MP2 encoding via libtwolame [no]
|
--enable-libtwolame enable MP2 encoding via libtwolame [no]
|
||||||
--enable-libuavs3d enable AVS3 decoding via libuavs3d [no]
|
--enable-libuavs3d enable AVS3 decoding via libuavs3d [no]
|
||||||
--enable-libv4l2 enable libv4l2/v4l-utils [no]
|
--enable-libv4l2 enable libv4l2/v4l-utils [no]
|
||||||
|
@ -386,7 +387,9 @@ Toolchain options:
|
||||||
--windres=WINDRES use windows resource compiler WINDRES [$windres_default]
|
--windres=WINDRES use windows resource compiler WINDRES [$windres_default]
|
||||||
--x86asmexe=EXE use nasm-compatible assembler EXE [$x86asmexe_default]
|
--x86asmexe=EXE use nasm-compatible assembler EXE [$x86asmexe_default]
|
||||||
--cc=CC use C compiler CC [$cc_default]
|
--cc=CC use C compiler CC [$cc_default]
|
||||||
|
--stdc=STDC use C standard STDC [$stdc_default]
|
||||||
--cxx=CXX use C compiler CXX [$cxx_default]
|
--cxx=CXX use C compiler CXX [$cxx_default]
|
||||||
|
--stdcxx=STDCXX use C standard STDCXX [$stdcxx_default]
|
||||||
--objcc=OCC use ObjC compiler OCC [$cc_default]
|
--objcc=OCC use ObjC compiler OCC [$cc_default]
|
||||||
--dep-cc=DEPCC use dependency generator DEPCC [$cc_default]
|
--dep-cc=DEPCC use dependency generator DEPCC [$cc_default]
|
||||||
--nvcc=NVCC use Nvidia CUDA compiler NVCC or clang [$nvcc_default]
|
--nvcc=NVCC use Nvidia CUDA compiler NVCC or clang [$nvcc_default]
|
||||||
|
@ -1453,6 +1456,33 @@ test_cflags_cc(){
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_cflags_cc(){
|
||||||
|
log check_cflags_cc "$@"
|
||||||
|
flags=$1
|
||||||
|
test_cflags_cc "$@" && add_cflags $flags
|
||||||
|
}
|
||||||
|
|
||||||
|
test_cxxflags_cc(){
|
||||||
|
log test_cxxflags_cc "$@"
|
||||||
|
flags=$1
|
||||||
|
header=$2
|
||||||
|
condition=$3
|
||||||
|
shift 3
|
||||||
|
set -- $($cflags_filter "$flags")
|
||||||
|
test_cxx "$@" <<EOF
|
||||||
|
#include <$header>
|
||||||
|
#if !($condition)
|
||||||
|
#error "unsatisfied condition: $condition"
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
check_cxxflags_cc(){
|
||||||
|
log check_cxxflags_cc "$@"
|
||||||
|
flags=$1
|
||||||
|
test_cxxflags_cc "$@" && add_cxxflags $flags
|
||||||
|
}
|
||||||
|
|
||||||
check_lib(){
|
check_lib(){
|
||||||
log check_lib "$@"
|
log check_lib "$@"
|
||||||
name="$1"
|
name="$1"
|
||||||
|
@ -1694,6 +1724,27 @@ int x;
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_host_cflags_cc(){
|
||||||
|
log test_host_cflags_cc "$@"
|
||||||
|
flags=$1
|
||||||
|
header=$2
|
||||||
|
condition=$3
|
||||||
|
shift 3
|
||||||
|
set -- $($host_cflags_filter "$flags")
|
||||||
|
test_host_cc "$@" <<EOF
|
||||||
|
#include <$header>
|
||||||
|
#if !($condition)
|
||||||
|
#error "unsatisfied condition: $condition"
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
check_host_cflags_cc(){
|
||||||
|
log check_host_cflags_cc "$@"
|
||||||
|
flags=$1
|
||||||
|
test_host_cflags_cc "$@" && add_host_cflags $flags
|
||||||
|
}
|
||||||
|
|
||||||
test_host_cpp_condition(){
|
test_host_cpp_condition(){
|
||||||
log test_host_cpp_condition "$@"
|
log test_host_cpp_condition "$@"
|
||||||
header=$1
|
header=$1
|
||||||
|
@ -1905,6 +1956,7 @@ EXTERNAL_LIBRARY_LIST="
|
||||||
libtensorflow
|
libtensorflow
|
||||||
libtesseract
|
libtesseract
|
||||||
libtheora
|
libtheora
|
||||||
|
libtorch
|
||||||
libtwolame
|
libtwolame
|
||||||
libuavs3d
|
libuavs3d
|
||||||
libv4l2
|
libv4l2
|
||||||
|
@ -2403,6 +2455,9 @@ TOOLCHAIN_FEATURES="
|
||||||
TYPES_LIST="
|
TYPES_LIST="
|
||||||
DPI_AWARENESS_CONTEXT
|
DPI_AWARENESS_CONTEXT
|
||||||
IDXGIOutput5
|
IDXGIOutput5
|
||||||
|
DXVA_PicParams_AV1
|
||||||
|
DXVA_PicParams_HEVC
|
||||||
|
DXVA_PicParams_VP9
|
||||||
kCMVideoCodecType_HEVC
|
kCMVideoCodecType_HEVC
|
||||||
kCMVideoCodecType_HEVCWithAlpha
|
kCMVideoCodecType_HEVCWithAlpha
|
||||||
kCMVideoCodecType_VP9
|
kCMVideoCodecType_VP9
|
||||||
|
@ -2531,6 +2586,7 @@ CONFIG_EXTRA="
|
||||||
jpegtables
|
jpegtables
|
||||||
lgplv3
|
lgplv3
|
||||||
libx262
|
libx262
|
||||||
|
libx264_hdr10
|
||||||
llauddsp
|
llauddsp
|
||||||
llviddsp
|
llviddsp
|
||||||
llvidencdsp
|
llvidencdsp
|
||||||
|
@ -2650,6 +2706,8 @@ CMDLINE_SET="
|
||||||
random_seed
|
random_seed
|
||||||
ranlib
|
ranlib
|
||||||
samples
|
samples
|
||||||
|
stdc
|
||||||
|
stdcxx
|
||||||
strip
|
strip
|
||||||
sws_max_filter_size
|
sws_max_filter_size
|
||||||
sysinclude
|
sysinclude
|
||||||
|
@ -2785,7 +2843,7 @@ cbs_vp9_select="cbs"
|
||||||
deflate_wrapper_deps="zlib"
|
deflate_wrapper_deps="zlib"
|
||||||
dirac_parse_select="golomb"
|
dirac_parse_select="golomb"
|
||||||
dovi_rpu_select="golomb"
|
dovi_rpu_select="golomb"
|
||||||
dnn_suggest="libtensorflow libopenvino"
|
dnn_suggest="libtensorflow libopenvino libtorch"
|
||||||
dnn_deps="avformat swscale"
|
dnn_deps="avformat swscale"
|
||||||
error_resilience_select="me_cmp"
|
error_resilience_select="me_cmp"
|
||||||
evcparse_select="golomb"
|
evcparse_select="golomb"
|
||||||
|
@ -3079,13 +3137,13 @@ videotoolbox_hwaccel_extralibs="-framework QuartzCore"
|
||||||
vulkan_deps="threads"
|
vulkan_deps="threads"
|
||||||
vulkan_deps_any="libdl LoadLibrary"
|
vulkan_deps_any="libdl LoadLibrary"
|
||||||
|
|
||||||
av1_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_AV1"
|
av1_d3d11va_hwaccel_deps="d3d11va"
|
||||||
av1_d3d11va_hwaccel_select="av1_decoder"
|
av1_d3d11va_hwaccel_select="av1_decoder"
|
||||||
av1_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_AV1"
|
av1_d3d11va2_hwaccel_deps="d3d11va"
|
||||||
av1_d3d11va2_hwaccel_select="av1_decoder"
|
av1_d3d11va2_hwaccel_select="av1_decoder"
|
||||||
av1_d3d12va_hwaccel_deps="d3d12va DXVA_PicParams_AV1"
|
av1_d3d12va_hwaccel_deps="d3d12va"
|
||||||
av1_d3d12va_hwaccel_select="av1_decoder"
|
av1_d3d12va_hwaccel_select="av1_decoder"
|
||||||
av1_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_AV1"
|
av1_dxva2_hwaccel_deps="dxva2"
|
||||||
av1_dxva2_hwaccel_select="av1_decoder"
|
av1_dxva2_hwaccel_select="av1_decoder"
|
||||||
av1_nvdec_hwaccel_deps="nvdec CUVIDAV1PICPARAMS"
|
av1_nvdec_hwaccel_deps="nvdec CUVIDAV1PICPARAMS"
|
||||||
av1_nvdec_hwaccel_select="av1_decoder"
|
av1_nvdec_hwaccel_select="av1_decoder"
|
||||||
|
@ -3117,13 +3175,13 @@ h264_videotoolbox_hwaccel_deps="videotoolbox"
|
||||||
h264_videotoolbox_hwaccel_select="h264_decoder"
|
h264_videotoolbox_hwaccel_select="h264_decoder"
|
||||||
h264_vulkan_hwaccel_deps="vulkan"
|
h264_vulkan_hwaccel_deps="vulkan"
|
||||||
h264_vulkan_hwaccel_select="h264_decoder"
|
h264_vulkan_hwaccel_select="h264_decoder"
|
||||||
hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
|
hevc_d3d11va_hwaccel_deps="d3d11va"
|
||||||
hevc_d3d11va_hwaccel_select="hevc_decoder"
|
hevc_d3d11va_hwaccel_select="hevc_decoder"
|
||||||
hevc_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
|
hevc_d3d11va2_hwaccel_deps="d3d11va"
|
||||||
hevc_d3d11va2_hwaccel_select="hevc_decoder"
|
hevc_d3d11va2_hwaccel_select="hevc_decoder"
|
||||||
hevc_d3d12va_hwaccel_deps="d3d12va DXVA_PicParams_HEVC"
|
hevc_d3d12va_hwaccel_deps="d3d12va"
|
||||||
hevc_d3d12va_hwaccel_select="hevc_decoder"
|
hevc_d3d12va_hwaccel_select="hevc_decoder"
|
||||||
hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
|
hevc_dxva2_hwaccel_deps="dxva2"
|
||||||
hevc_dxva2_hwaccel_select="hevc_decoder"
|
hevc_dxva2_hwaccel_select="hevc_decoder"
|
||||||
hevc_nvdec_hwaccel_deps="nvdec"
|
hevc_nvdec_hwaccel_deps="nvdec"
|
||||||
hevc_nvdec_hwaccel_select="hevc_decoder"
|
hevc_nvdec_hwaccel_select="hevc_decoder"
|
||||||
|
@ -3189,13 +3247,13 @@ vp8_nvdec_hwaccel_deps="nvdec"
|
||||||
vp8_nvdec_hwaccel_select="vp8_decoder"
|
vp8_nvdec_hwaccel_select="vp8_decoder"
|
||||||
vp8_vaapi_hwaccel_deps="vaapi"
|
vp8_vaapi_hwaccel_deps="vaapi"
|
||||||
vp8_vaapi_hwaccel_select="vp8_decoder"
|
vp8_vaapi_hwaccel_select="vp8_decoder"
|
||||||
vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
|
vp9_d3d11va_hwaccel_deps="d3d11va"
|
||||||
vp9_d3d11va_hwaccel_select="vp9_decoder"
|
vp9_d3d11va_hwaccel_select="vp9_decoder"
|
||||||
vp9_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
|
vp9_d3d11va2_hwaccel_deps="d3d11va"
|
||||||
vp9_d3d11va2_hwaccel_select="vp9_decoder"
|
vp9_d3d11va2_hwaccel_select="vp9_decoder"
|
||||||
vp9_d3d12va_hwaccel_deps="d3d12va DXVA_PicParams_VP9"
|
vp9_d3d12va_hwaccel_deps="d3d12va"
|
||||||
vp9_d3d12va_hwaccel_select="vp9_decoder"
|
vp9_d3d12va_hwaccel_select="vp9_decoder"
|
||||||
vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9"
|
vp9_dxva2_hwaccel_deps="dxva2"
|
||||||
vp9_dxva2_hwaccel_select="vp9_decoder"
|
vp9_dxva2_hwaccel_select="vp9_decoder"
|
||||||
vp9_nvdec_hwaccel_deps="nvdec"
|
vp9_nvdec_hwaccel_deps="nvdec"
|
||||||
vp9_nvdec_hwaccel_select="vp9_decoder"
|
vp9_nvdec_hwaccel_select="vp9_decoder"
|
||||||
|
@ -3484,7 +3542,7 @@ libwebp_encoder_deps="libwebp"
|
||||||
libwebp_anim_encoder_deps="libwebp"
|
libwebp_anim_encoder_deps="libwebp"
|
||||||
libx262_encoder_deps="libx262"
|
libx262_encoder_deps="libx262"
|
||||||
libx264_encoder_deps="libx264"
|
libx264_encoder_deps="libx264"
|
||||||
libx264_encoder_select="atsc_a53"
|
libx264_encoder_select="atsc_a53 golomb"
|
||||||
libx264rgb_encoder_deps="libx264"
|
libx264rgb_encoder_deps="libx264"
|
||||||
libx264rgb_encoder_select="libx264_encoder"
|
libx264rgb_encoder_select="libx264_encoder"
|
||||||
libx265_encoder_deps="libx265"
|
libx265_encoder_deps="libx265"
|
||||||
|
@ -3656,6 +3714,8 @@ xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes"
|
||||||
xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
|
xv_outdev_deps="xlib_xv xlib_x11 xlib_xext"
|
||||||
|
|
||||||
# protocols
|
# protocols
|
||||||
|
android_content_protocol_deps="jni"
|
||||||
|
android_content_protocol_select="file_protocol"
|
||||||
async_protocol_deps="threads"
|
async_protocol_deps="threads"
|
||||||
bluray_protocol_deps="libbluray"
|
bluray_protocol_deps="libbluray"
|
||||||
ffrtmpcrypt_protocol_conflict="librtmp_protocol"
|
ffrtmpcrypt_protocol_conflict="librtmp_protocol"
|
||||||
|
@ -3978,6 +4038,8 @@ mandir_default='${prefix}/share/man'
|
||||||
# toolchain
|
# toolchain
|
||||||
ar_default="ar"
|
ar_default="ar"
|
||||||
cc_default="gcc"
|
cc_default="gcc"
|
||||||
|
stdc_default="c17"
|
||||||
|
stdcxx_default="c++11"
|
||||||
cxx_default="g++"
|
cxx_default="g++"
|
||||||
host_cc_default="gcc"
|
host_cc_default="gcc"
|
||||||
doxygen_default="doxygen"
|
doxygen_default="doxygen"
|
||||||
|
@ -4585,7 +4647,7 @@ if enabled cuda_nvcc; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \
|
set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \
|
||||||
target_exec x86asmexe metalcc metallib
|
target_exec x86asmexe metalcc metallib stdc stdcxx
|
||||||
enabled cross_compile || host_cc_default=$cc
|
enabled cross_compile || host_cc_default=$cc
|
||||||
set_default host_cc
|
set_default host_cc
|
||||||
|
|
||||||
|
@ -4755,7 +4817,7 @@ icl_flags(){
|
||||||
# Despite what Intel's documentation says -Wall, which is supported
|
# Despite what Intel's documentation says -Wall, which is supported
|
||||||
# on Windows, does enable remarks so disable them here.
|
# on Windows, does enable remarks so disable them here.
|
||||||
-Wall) echo $flag -Qdiag-disable:remark ;;
|
-Wall) echo $flag -Qdiag-disable:remark ;;
|
||||||
-std=c11) echo -Qstd=c11 ;;
|
-std=$stdc) echo -Qstd=$stdc ;;
|
||||||
-flto*) echo -ipo ;;
|
-flto*) echo -ipo ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
@ -4803,7 +4865,7 @@ suncc_flags(){
|
||||||
athlon*) echo -xarch=pentium_proa ;;
|
athlon*) echo -xarch=pentium_proa ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
-std=c11) echo -xc11 ;;
|
-std=$stdc) echo -x$stdc ;;
|
||||||
-fomit-frame-pointer) echo -xregs=frameptr ;;
|
-fomit-frame-pointer) echo -xregs=frameptr ;;
|
||||||
-fPIC) echo -KPIC -xcode=pic32 ;;
|
-fPIC) echo -KPIC -xcode=pic32 ;;
|
||||||
-W*,*) echo $flag ;;
|
-W*,*) echo $flag ;;
|
||||||
|
@ -4892,8 +4954,8 @@ probe_cc(){
|
||||||
_type=suncc
|
_type=suncc
|
||||||
_ident=$($_cc -V 2>&1 | head -n1 | cut -d' ' -f 2-)
|
_ident=$($_cc -V 2>&1 | head -n1 | cut -d' ' -f 2-)
|
||||||
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< | sed -e "1s,^.*: ,$@: ," -e "\$$!s,\$$, \\\," -e "1!s,^.*: , ," > $(@:.o=.d)'
|
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< | sed -e "1s,^.*: ,$@: ," -e "\$$!s,\$$, \\\," -e "1!s,^.*: , ," > $(@:.o=.d)'
|
||||||
_DEPFLAGS='-xM1 -xc11'
|
_DEPFLAGS='-xM1 -x$stdc'
|
||||||
_ldflags='-std=c11'
|
_ldflags='-std=$stdc'
|
||||||
_cflags_speed='-O5'
|
_cflags_speed='-O5'
|
||||||
_cflags_size='-O5 -xspace'
|
_cflags_size='-O5 -xspace'
|
||||||
_flags_filter=suncc_flags
|
_flags_filter=suncc_flags
|
||||||
|
@ -5524,18 +5586,21 @@ fi
|
||||||
|
|
||||||
add_cppflags -D_ISOC11_SOURCE
|
add_cppflags -D_ISOC11_SOURCE
|
||||||
add_cxxflags -D__STDC_CONSTANT_MACROS
|
add_cxxflags -D__STDC_CONSTANT_MACROS
|
||||||
check_cxxflags -std=c++11 || check_cxxflags -std=c++0x
|
check_cxxflags_cc -std=$stdcxx ctype.h "__cplusplus >= 201103L" ||
|
||||||
|
{ check_cxxflags -std=c++11 && stdcxx="c++11" || { check_cxxflags -std=c++0x && stdcxx="c++0x"; }; }
|
||||||
|
|
||||||
# some compilers silently accept -std=c11, so we also need to check that the
|
# some compilers silently accept -std=c11, so we also need to check that the
|
||||||
# version macro is defined properly
|
# version macro is defined properly
|
||||||
test_cflags_cc -std=c11 ctype.h "__STDC_VERSION__ >= 201112L" &&
|
check_cflags_cc -std=$stdc ctype.h "__STDC_VERSION__ >= 201112L" ||
|
||||||
add_cflags -std=c11 || die "Compiler lacks C11 support"
|
{ check_cflags_cc -std=c11 ctype.h "__STDC_VERSION__ >= 201112L" && stdc="c11" || die "Compiler lacks C11 support"; }
|
||||||
|
|
||||||
check_cppflags -D_FILE_OFFSET_BITS=64
|
check_cppflags -D_FILE_OFFSET_BITS=64
|
||||||
check_cppflags -D_LARGEFILE_SOURCE
|
check_cppflags -D_LARGEFILE_SOURCE
|
||||||
|
|
||||||
add_host_cppflags -D_ISOC11_SOURCE
|
add_host_cppflags -D_ISOC11_SOURCE
|
||||||
check_host_cflags -std=c11
|
check_host_cflags_cc -std=$stdc ctype.h "__STDC_VERSION__ >= 201112L" ||
|
||||||
|
check_host_cflags_cc -std=c11 ctype.h "__STDC_VERSION__ >= 201112L" || die "Host compiler lacks C11 support"
|
||||||
|
|
||||||
check_host_cflags -Wall
|
check_host_cflags -Wall
|
||||||
check_host_cflags $host_cflags_speed
|
check_host_cflags $host_cflags_speed
|
||||||
|
|
||||||
|
@ -6877,13 +6942,14 @@ enabled libsmbclient && { check_pkg_config libsmbclient smbclient libsmbcli
|
||||||
enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy -lstdc++
|
enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy -lstdc++
|
||||||
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
|
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
|
||||||
enabled libssh && require_pkg_config libssh "libssh >= 0.6.0" libssh/sftp.h sftp_init
|
enabled libssh && require_pkg_config libssh "libssh >= 0.6.0" libssh/sftp.h sftp_init
|
||||||
enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
|
enabled libspeex && require libspeex speex/speex.h speex_decoder_init -lspeex
|
||||||
enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
|
enabled libsrt && require_pkg_config libsrt "srt >= 1.3.0" srt/srt.h srt_socket
|
||||||
enabled libsvtav1 && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.9.0" EbSvtAv1Enc.h svt_av1_enc_init_handle
|
enabled libsvtav1 && require_pkg_config libsvtav1 "SvtAv1Enc >= 0.9.0" EbSvtAv1Enc.h svt_av1_enc_init_handle
|
||||||
enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow
|
enabled libtensorflow && require libtensorflow tensorflow/c/c_api.h TF_Version -ltensorflow
|
||||||
enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
|
enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
|
||||||
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
|
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
|
||||||
enabled libtls && require_pkg_config libtls libtls tls.h tls_configure
|
enabled libtls && require_pkg_config libtls libtls tls.h tls_configure
|
||||||
|
enabled libtorch && check_cxxflags -std=c++17 && require_cpp libtorch torch/torch.h "torch::Tensor" -ltorch -lc10 -ltorch_cpu -lstdc++ -lpthread
|
||||||
enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame &&
|
enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame &&
|
||||||
{ check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
|
{ check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
|
||||||
die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
|
die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
|
||||||
|
@ -6925,6 +6991,7 @@ enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x
|
||||||
require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
|
require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
|
||||||
[ "$toolchain" != "msvc" ] ||
|
[ "$toolchain" != "msvc" ] ||
|
||||||
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
|
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
|
||||||
|
check_cpp_condition libx264_hdr10 x264.h "X264_BUILD >= 163" &&
|
||||||
check_cpp_condition libx262 x264.h "X264_MPEG2"
|
check_cpp_condition libx262 x264.h "X264_MPEG2"
|
||||||
enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get &&
|
enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get &&
|
||||||
require_cpp_condition libx265 x265.h "X265_BUILD >= 89"
|
require_cpp_condition libx265 x265.h "X265_BUILD >= 89"
|
||||||
|
|
|
@ -2,6 +2,32 @@ The last version increases of all libraries were on 2024-03-07
|
||||||
|
|
||||||
API changes, most recent first:
|
API changes, most recent first:
|
||||||
|
|
||||||
|
2024-03-xx - xxxxxxxxxx - lavu 59.6.100 - film_grain_params.h
|
||||||
|
Add av_film_grain_params_select().
|
||||||
|
|
||||||
|
2024-03-xx - xxxxxxxxxx - lavu 59.5.100 - film_grain_params.h
|
||||||
|
Add AVFilmGrainParams.color_range, color_primaries, color_trc, color_space,
|
||||||
|
width, height, subsampling_x, subsampling_y, bit_depth_luma and
|
||||||
|
bit_depth_chroma. Deprecate the corresponding fields from
|
||||||
|
AVFilmGrainH274Params.
|
||||||
|
|
||||||
|
2024-03-xx - xxxxxxxxxx - lavc 61.3.100 - jni.h
|
||||||
|
Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx().
|
||||||
|
|
||||||
|
2024-03-22 - xxxxxxxxxx - lavu 59.4.100 - frame.h
|
||||||
|
Constified the first-level pointee of av_frame_side_data_get()
|
||||||
|
and renamed it to av_frame_side_data_get_c(). From now on,
|
||||||
|
av_frame_side_data_get() is a wrapper around av_frame_side_data_get_c()
|
||||||
|
that accepts AVFrameSideData * const *sd.
|
||||||
|
|
||||||
|
2024-03-xx - xxxxxxxxxx - lavc 61.2.100 - avcodec.h
|
||||||
|
Add AVCodecContext.[nb_]decoded_side_data.
|
||||||
|
|
||||||
|
2024-03-xx - xxxxxxxxxx - lavu 59.3.100 - frame.h
|
||||||
|
Add av_frame_side_data_free(), av_frame_side_data_new(),
|
||||||
|
av_frame_side_data_clone(), av_frame_side_data_get() as well
|
||||||
|
as AV_FRAME_SIDE_DATA_FLAG_UNIQUE.
|
||||||
|
|
||||||
2024-03-xx - xxxxxxxxxx - lavu 59.2.100 - channel_layout.h
|
2024-03-xx - xxxxxxxxxx - lavu 59.2.100 - channel_layout.h
|
||||||
Add AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL.
|
Add AV_CHANNEL_LAYOUT_RETYPE_FLAG_CANONICAL.
|
||||||
|
|
||||||
|
|
|
@ -1576,19 +1576,35 @@ This image format is used to store astronomical data.
|
||||||
For more information regarding the format, visit
|
For more information regarding the format, visit
|
||||||
@url{https://fits.gsfc.nasa.gov}.
|
@url{https://fits.gsfc.nasa.gov}.
|
||||||
|
|
||||||
@section flv
|
@section flac
|
||||||
|
Raw FLAC audio muxer.
|
||||||
|
|
||||||
|
This muxer accepts exactly one FLAC audio stream. Additionally, it is possible to add
|
||||||
|
images with disposition @samp{attached_pic}.
|
||||||
|
|
||||||
|
@subsection Options
|
||||||
|
@table @option
|
||||||
|
@item write_header @var{bool}
|
||||||
|
write the file header if set to @code{true}, default is @code{true}
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@subsection Example
|
||||||
|
Use @command{ffmpeg} to store the audio stream from an input file,
|
||||||
|
together with several pictures used with @samp{attached_pic}
|
||||||
|
disposition:
|
||||||
|
@example
|
||||||
|
ffmpeg -i INPUT -i pic1.png -i pic2.jpg -map 0:a -map 1 -map 2 -disposition:v attached_pic OUTPUT
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@section flv
|
||||||
Adobe Flash Video Format muxer.
|
Adobe Flash Video Format muxer.
|
||||||
|
|
||||||
This muxer accepts the following options:
|
@subsection Options
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
|
|
||||||
@item flvflags @var{flags}
|
@item flvflags @var{flags}
|
||||||
Possible values:
|
Possible values:
|
||||||
|
|
||||||
@table @samp
|
@table @samp
|
||||||
|
|
||||||
@item aac_seq_header_detect
|
@item aac_seq_header_detect
|
||||||
Place AAC sequence header based on audio stream data.
|
Place AAC sequence header based on audio stream data.
|
||||||
|
|
||||||
|
@ -1729,24 +1745,26 @@ See also the @ref{framehash} and @ref{md5} muxers.
|
||||||
|
|
||||||
@anchor{gif}
|
@anchor{gif}
|
||||||
@section gif
|
@section gif
|
||||||
|
|
||||||
Animated GIF muxer.
|
Animated GIF muxer.
|
||||||
|
|
||||||
It accepts the following options:
|
Note that the GIF format has a very large time base: the delay between two frames can
|
||||||
|
therefore not be smaller than one centi second.
|
||||||
|
|
||||||
|
@subsection Options
|
||||||
@table @option
|
@table @option
|
||||||
@item loop
|
@item loop @var{bool}
|
||||||
Set the number of times to loop the output. Use @code{-1} for no loop, @code{0}
|
Set the number of times to loop the output. Use @code{-1} for no loop, @code{0}
|
||||||
for looping indefinitely (default).
|
for looping indefinitely (default).
|
||||||
|
|
||||||
@item final_delay
|
@item final_delay @var{delay}
|
||||||
Force the delay (expressed in centiseconds) after the last frame. Each frame
|
Force the delay (expressed in centiseconds) after the last frame. Each frame
|
||||||
ends with a delay until the next frame. The default is @code{-1}, which is a
|
ends with a delay until the next frame. The default is @code{-1}, which is a
|
||||||
special value to tell the muxer to re-use the previous delay. In case of a
|
special value to tell the muxer to re-use the previous delay. In case of a
|
||||||
loop, you might want to customize this value to mark a pause for instance.
|
loop, you might want to customize this value to mark a pause for instance.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
For example, to encode a gif looping 10 times, with a 5 seconds delay between
|
@subsection Example
|
||||||
|
Encode a gif looping 10 times, with a 5 seconds delay between
|
||||||
the loops:
|
the loops:
|
||||||
@example
|
@example
|
||||||
ffmpeg -i INPUT -loop 10 -final_delay 500 out.gif
|
ffmpeg -i INPUT -loop 10 -final_delay 500 out.gif
|
||||||
|
@ -1758,8 +1776,17 @@ force the @ref{image2} muxer:
|
||||||
ffmpeg -i INPUT -c:v gif -f image2 "out%d.gif"
|
ffmpeg -i INPUT -c:v gif -f image2 "out%d.gif"
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Note 2: the GIF format has a very large time base: the delay between two frames
|
@section gxf
|
||||||
can therefore not be smaller than one centi second.
|
General eXchange Format (GXF) muxer.
|
||||||
|
|
||||||
|
GXF was developed by Grass Valley Group, then standardized by SMPTE as SMPTE
|
||||||
|
360M and was extended in SMPTE RDD 14-2007 to include high-definition video
|
||||||
|
resolutions.
|
||||||
|
|
||||||
|
It accepts at most one video stream with codec @samp{mjpeg}, or
|
||||||
|
@samp{mpeg1video}, or @samp{mpeg2video}, or @samp{dvvideo} with resolution
|
||||||
|
@samp{512x480} or @samp{608x576}, and several audio streams with rate 48000Hz
|
||||||
|
and codec @samp{pcm16_le}.
|
||||||
|
|
||||||
@anchor{hash}
|
@anchor{hash}
|
||||||
@section hash
|
@section hash
|
||||||
|
@ -1806,6 +1833,45 @@ ffmpeg -i INPUT -f hash -hash md5 -
|
||||||
|
|
||||||
See also the @ref{framehash} muxer.
|
See also the @ref{framehash} muxer.
|
||||||
|
|
||||||
|
@anchor{hds}
|
||||||
|
@section hds
|
||||||
|
HTTP Dynamic Streaming (HDS) muxer.
|
||||||
|
|
||||||
|
HTTP dynamic streaming, or HDS, is an adaptive bitrate streaming method
|
||||||
|
developed by Adobe. HDS delivers MP4 video content over HTTP connections. HDS
|
||||||
|
can be used for on-demand streaming or live streaming.
|
||||||
|
|
||||||
|
This muxer creates an .f4m (Adobe Flash Media Manifest File) manifest, an .abst
|
||||||
|
(Adobe Bootstrap File) for each stream, and segment files in a directory
|
||||||
|
specified as the output.
|
||||||
|
|
||||||
|
These needs to be accessed by an HDS player throuhg HTTPS for it to be able to
|
||||||
|
perform playback on the generated stream.
|
||||||
|
|
||||||
|
@subsection Options
|
||||||
|
@table @option
|
||||||
|
@item extra_window_size @var{int}
|
||||||
|
number of fragments kept outside of the manifest before removing from disk
|
||||||
|
|
||||||
|
@item min_frag_duration @var{microseconds}
|
||||||
|
minimum fragment duration (in microseconds), default value is 1 second
|
||||||
|
(@code{10000000})
|
||||||
|
|
||||||
|
@item remove_at_exit @var{bool}
|
||||||
|
remove all fragments when finished when set to @code{true}
|
||||||
|
|
||||||
|
@item window_size @var{int}
|
||||||
|
number of fragments kept in the manifest, if set to a value different from
|
||||||
|
@code{0}. By default all segments are kept in the output directory.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@subsection Example
|
||||||
|
Use @command{ffmpeg} to generate HDS files to the @file{output.hds} directory in
|
||||||
|
real-time rate:
|
||||||
|
@example
|
||||||
|
ffmpeg -re -i INPUT -f hds -b:v 200k output.hds
|
||||||
|
@end example
|
||||||
|
|
||||||
@anchor{hls}
|
@anchor{hls}
|
||||||
@section hls
|
@section hls
|
||||||
|
|
||||||
|
|
|
@ -5,3 +5,4 @@
|
||||||
/config.log
|
/config.log
|
||||||
/config.mak
|
/config.mak
|
||||||
/config.sh
|
/config.sh
|
||||||
|
/config.out
|
||||||
|
|
|
@ -1207,6 +1207,19 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dp->dec_ctx->hw_device_ctx) {
|
||||||
|
// Update decoder extra_hw_frames option to account for the
|
||||||
|
// frames held in queues inside the ffmpeg utility. This is
|
||||||
|
// called after avcodec_open2() because the user-set value of
|
||||||
|
// extra_hw_frames becomes valid in there, and we need to add
|
||||||
|
// this on top of it.
|
||||||
|
int extra_frames = DEFAULT_FRAME_THREAD_QUEUE_SIZE;
|
||||||
|
if (dp->dec_ctx->extra_hw_frames >= 0)
|
||||||
|
dp->dec_ctx->extra_hw_frames += extra_frames;
|
||||||
|
else
|
||||||
|
dp->dec_ctx->extra_hw_frames = extra_frames;
|
||||||
|
}
|
||||||
|
|
||||||
ret = check_avoptions(*dec_opts);
|
ret = check_avoptions(*dec_opts);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -246,6 +246,21 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||||
enc_ctx->colorspace = frame->colorspace;
|
enc_ctx->colorspace = frame->colorspace;
|
||||||
enc_ctx->chroma_sample_location = frame->chroma_location;
|
enc_ctx->chroma_sample_location = frame->chroma_location;
|
||||||
|
|
||||||
|
for (int i = 0; i < frame->nb_side_data; i++) {
|
||||||
|
ret = av_frame_side_data_clone(
|
||||||
|
&enc_ctx->decoded_side_data, &enc_ctx->nb_decoded_side_data,
|
||||||
|
frame->side_data[i], AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_frame_side_data_free(
|
||||||
|
&enc_ctx->decoded_side_data,
|
||||||
|
&enc_ctx->nb_decoded_side_data);
|
||||||
|
av_log(NULL, AV_LOG_ERROR,
|
||||||
|
"failed to configure video encoder: %s!\n",
|
||||||
|
av_err2str(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) ||
|
if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) ||
|
||||||
(frame->flags & AV_FRAME_FLAG_INTERLACED)
|
(frame->flags & AV_FRAME_FLAG_INTERLACED)
|
||||||
#if FFMPEG_OPT_TOP
|
#if FFMPEG_OPT_TOP
|
||||||
|
@ -631,7 +646,6 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame,
|
||||||
if (frame) {
|
if (frame) {
|
||||||
FrameData *fd = frame_data(frame);
|
FrameData *fd = frame_data(frame);
|
||||||
|
|
||||||
fd = frame_data(frame);
|
|
||||||
if (!fd)
|
if (!fd)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
|
|
@ -365,7 +365,21 @@ static int queue_alloc(ThreadQueue **ptq, unsigned nb_streams, unsigned queue_si
|
||||||
ThreadQueue *tq;
|
ThreadQueue *tq;
|
||||||
ObjPool *op;
|
ObjPool *op;
|
||||||
|
|
||||||
queue_size = queue_size > 0 ? queue_size : 8;
|
if (queue_size <= 0) {
|
||||||
|
if (type == QUEUE_FRAMES)
|
||||||
|
queue_size = DEFAULT_FRAME_THREAD_QUEUE_SIZE;
|
||||||
|
else
|
||||||
|
queue_size = DEFAULT_PACKET_THREAD_QUEUE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == QUEUE_FRAMES) {
|
||||||
|
// This queue length is used in the decoder code to ensure that
|
||||||
|
// there are enough entries in fixed-size frame pools to account
|
||||||
|
// for frames held in queues inside the ffmpeg utility. If this
|
||||||
|
// can ever dynamically change then the corresponding decode
|
||||||
|
// code needs to be updated as well.
|
||||||
|
av_assert0(queue_size == DEFAULT_FRAME_THREAD_QUEUE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
op = (type == QUEUE_PACKETS) ? objpool_alloc_packets() :
|
op = (type == QUEUE_PACKETS) ? objpool_alloc_packets() :
|
||||||
objpool_alloc_frames();
|
objpool_alloc_frames();
|
||||||
|
|
|
@ -233,6 +233,18 @@ int sch_add_filtergraph(Scheduler *sch, unsigned nb_inputs, unsigned nb_outputs,
|
||||||
*/
|
*/
|
||||||
int sch_add_mux(Scheduler *sch, SchThreadFunc func, int (*init)(void *),
|
int sch_add_mux(Scheduler *sch, SchThreadFunc func, int (*init)(void *),
|
||||||
void *ctx, int sdp_auto, unsigned thread_queue_size);
|
void *ctx, int sdp_auto, unsigned thread_queue_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default size of a packet thread queue. For muxing this can be overridden by
|
||||||
|
* the thread_queue_size option as passed to a call to sch_add_mux().
|
||||||
|
*/
|
||||||
|
#define DEFAULT_PACKET_THREAD_QUEUE_SIZE 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default size of a frame thread queue.
|
||||||
|
*/
|
||||||
|
#define DEFAULT_FRAME_THREAD_QUEUE_SIZE 8
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a muxed stream for a previously added muxer.
|
* Add a muxed stream for a previously added muxer.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2040,6 +2040,8 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
if (force_output_format) {
|
if (force_output_format) {
|
||||||
|
av_bprint_clear(&bp);
|
||||||
|
av_channel_layout_describe_bprint(&is->audio_tgt.ch_layout, &bp);
|
||||||
sample_rates [0] = is->audio_tgt.freq;
|
sample_rates [0] = is->audio_tgt.freq;
|
||||||
if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
|
if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -2402,22 +2402,41 @@ static void print_ambient_viewing_environment(WriterContext *w,
|
||||||
static void print_film_grain_params(WriterContext *w,
|
static void print_film_grain_params(WriterContext *w,
|
||||||
const AVFilmGrainParams *fgp)
|
const AVFilmGrainParams *fgp)
|
||||||
{
|
{
|
||||||
|
const char *color_range, *color_primaries, *color_trc, *color_space;
|
||||||
|
const char *const film_grain_type_names[] = {
|
||||||
|
[AV_FILM_GRAIN_PARAMS_NONE] = "none",
|
||||||
|
[AV_FILM_GRAIN_PARAMS_AV1] = "av1",
|
||||||
|
[AV_FILM_GRAIN_PARAMS_H274] = "h274",
|
||||||
|
};
|
||||||
|
|
||||||
AVBPrint pbuf;
|
AVBPrint pbuf;
|
||||||
if (!fgp)
|
if (!fgp || fgp->type >= FF_ARRAY_ELEMS(film_grain_type_names))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
color_range = av_color_range_name(fgp->color_range);
|
||||||
|
color_primaries = av_color_primaries_name(fgp->color_primaries);
|
||||||
|
color_trc = av_color_transfer_name(fgp->color_trc);
|
||||||
|
color_space = av_color_space_name(fgp->color_space);
|
||||||
|
|
||||||
av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
|
av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
|
||||||
|
print_str("type", film_grain_type_names[fgp->type]);
|
||||||
|
print_fmt("seed", "%"PRIu64, fgp->seed);
|
||||||
|
print_int("width", fgp->width);
|
||||||
|
print_int("height", fgp->height);
|
||||||
|
print_int("subsampling_x", fgp->subsampling_x);
|
||||||
|
print_int("subsampling_y", fgp->subsampling_y);
|
||||||
|
print_str("color_range", color_range ? color_range : "unknown");
|
||||||
|
print_str("color_primaries", color_primaries ? color_primaries : "unknown");
|
||||||
|
print_str("color_trc", color_trc ? color_trc : "unknown");
|
||||||
|
print_str("color_space", color_space ? color_space : "unknown");
|
||||||
|
|
||||||
switch (fgp->type) {
|
switch (fgp->type) {
|
||||||
case AV_FILM_GRAIN_PARAMS_NONE:
|
case AV_FILM_GRAIN_PARAMS_NONE:
|
||||||
print_str("type", "none");
|
|
||||||
break;
|
break;
|
||||||
case AV_FILM_GRAIN_PARAMS_AV1: {
|
case AV_FILM_GRAIN_PARAMS_AV1: {
|
||||||
const AVFilmGrainAOMParams *aom = &fgp->codec.aom;
|
const AVFilmGrainAOMParams *aom = &fgp->codec.aom;
|
||||||
const int num_ar_coeffs_y = 2 * aom->ar_coeff_lag * (aom->ar_coeff_lag + 1);
|
const int num_ar_coeffs_y = 2 * aom->ar_coeff_lag * (aom->ar_coeff_lag + 1);
|
||||||
const int num_ar_coeffs_uv = num_ar_coeffs_y + !!aom->num_y_points;
|
const int num_ar_coeffs_uv = num_ar_coeffs_y + !!aom->num_y_points;
|
||||||
print_str("type", "av1");
|
|
||||||
print_fmt("seed", "%"PRIu64, fgp->seed);
|
|
||||||
print_int("chroma_scaling_from_luma", aom->chroma_scaling_from_luma);
|
print_int("chroma_scaling_from_luma", aom->chroma_scaling_from_luma);
|
||||||
print_int("scaling_shift", aom->scaling_shift);
|
print_int("scaling_shift", aom->scaling_shift);
|
||||||
print_int("ar_coeff_lag", aom->ar_coeff_lag);
|
print_int("ar_coeff_lag", aom->ar_coeff_lag);
|
||||||
|
@ -2431,6 +2450,7 @@ static void print_film_grain_params(WriterContext *w,
|
||||||
if (aom->num_y_points) {
|
if (aom->num_y_points) {
|
||||||
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
||||||
|
|
||||||
|
print_int("bit_depth_luma", fgp->bit_depth_luma);
|
||||||
print_list_fmt("y_points_value", "%"PRIu8, aom->num_y_points, 1, aom->y_points[idx][0]);
|
print_list_fmt("y_points_value", "%"PRIu8, aom->num_y_points, 1, aom->y_points[idx][0]);
|
||||||
print_list_fmt("y_points_scaling", "%"PRIu8, aom->num_y_points, 1, aom->y_points[idx][1]);
|
print_list_fmt("y_points_scaling", "%"PRIu8, aom->num_y_points, 1, aom->y_points[idx][1]);
|
||||||
print_list_fmt("ar_coeffs_y", "%"PRId8, num_ar_coeffs_y, 1, aom->ar_coeffs_y[idx]);
|
print_list_fmt("ar_coeffs_y", "%"PRId8, num_ar_coeffs_y, 1, aom->ar_coeffs_y[idx]);
|
||||||
|
@ -2445,6 +2465,7 @@ static void print_film_grain_params(WriterContext *w,
|
||||||
|
|
||||||
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
||||||
|
|
||||||
|
print_int("bit_depth_chroma", fgp->bit_depth_chroma);
|
||||||
print_list_fmt("uv_points_value", "%"PRIu8, aom->num_uv_points[uv], 1, aom->uv_points[uv][idx][0]);
|
print_list_fmt("uv_points_value", "%"PRIu8, aom->num_uv_points[uv], 1, aom->uv_points[uv][idx][0]);
|
||||||
print_list_fmt("uv_points_scaling", "%"PRIu8, aom->num_uv_points[uv], 1, aom->uv_points[uv][idx][1]);
|
print_list_fmt("uv_points_scaling", "%"PRIu8, aom->num_uv_points[uv], 1, aom->uv_points[uv][idx][1]);
|
||||||
print_list_fmt("ar_coeffs_uv", "%"PRId8, num_ar_coeffs_uv, 1, aom->ar_coeffs_uv[uv][idx]);
|
print_list_fmt("ar_coeffs_uv", "%"PRId8, num_ar_coeffs_uv, 1, aom->ar_coeffs_uv[uv][idx]);
|
||||||
|
@ -2462,17 +2483,7 @@ static void print_film_grain_params(WriterContext *w,
|
||||||
}
|
}
|
||||||
case AV_FILM_GRAIN_PARAMS_H274: {
|
case AV_FILM_GRAIN_PARAMS_H274: {
|
||||||
const AVFilmGrainH274Params *h274 = &fgp->codec.h274;
|
const AVFilmGrainH274Params *h274 = &fgp->codec.h274;
|
||||||
const char *color_range_str = av_color_range_name(h274->color_range);
|
|
||||||
const char *color_primaries_str = av_color_primaries_name(h274->color_primaries);
|
|
||||||
const char *color_trc_str = av_color_transfer_name(h274->color_trc);
|
|
||||||
const char *color_space_str = av_color_space_name(h274->color_space);
|
|
||||||
print_str("type", "h274");
|
|
||||||
print_fmt("seed", "%"PRIu64, fgp->seed);
|
|
||||||
print_int("model_id", h274->model_id);
|
print_int("model_id", h274->model_id);
|
||||||
print_str("color_range", color_range_str ? color_range_str : "unknown");
|
|
||||||
print_str("color_primaries", color_primaries_str ? color_primaries_str : "unknown");
|
|
||||||
print_str("color_trc", color_trc_str ? color_trc_str : "unknown");
|
|
||||||
print_str("color_space", color_space_str ? color_space_str : "unknown");
|
|
||||||
print_int("blending_mode_id", h274->blending_mode_id);
|
print_int("blending_mode_id", h274->blending_mode_id);
|
||||||
print_int("log2_scale_factor", h274->log2_scale_factor);
|
print_int("log2_scale_factor", h274->log2_scale_factor);
|
||||||
|
|
||||||
|
@ -2483,7 +2494,7 @@ static void print_film_grain_params(WriterContext *w,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_COMPONENT);
|
||||||
print_int(c ? "bit_depth_chroma" : "bit_depth_luma", c ? h274->bit_depth_chroma : h274->bit_depth_luma);
|
print_int(c ? "bit_depth_chroma" : "bit_depth_luma", c ? fgp->bit_depth_chroma : fgp->bit_depth_luma);
|
||||||
|
|
||||||
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST);
|
writer_print_section_header(w, NULL, SECTION_ID_FRAME_SIDE_DATA_PIECE_LIST);
|
||||||
for (int i = 0; i < h274->num_intensity_intervals[c]; i++) {
|
for (int i = 0; i < h274->num_intensity_intervals[c]; i++) {
|
||||||
|
|
|
@ -105,7 +105,7 @@ OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
|
||||||
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
|
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
|
||||||
h2645data.o h2645_parse.o h2645_vui.o
|
h2645data.o h2645_parse.o h2645_vui.o
|
||||||
OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
|
OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
|
||||||
dynamic_hdr_vivid.o
|
dynamic_hdr_vivid.o aom_film_grain.o
|
||||||
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
|
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
|
||||||
OBJS-$(CONFIG_HUFFMAN) += huffman.o
|
OBJS-$(CONFIG_HUFFMAN) += huffman.o
|
||||||
OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
|
OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
|
||||||
|
@ -432,7 +432,7 @@ OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o
|
||||||
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
|
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
|
||||||
hevc_cabac.o hevc_refs.o hevcpred.o \
|
hevc_cabac.o hevc_refs.o hevcpred.o \
|
||||||
hevcdsp.o hevc_filter.o hevc_data.o \
|
hevcdsp.o hevc_filter.o hevc_data.o \
|
||||||
h274.o
|
h274.o aom_film_grain.o
|
||||||
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
|
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
|
||||||
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
|
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
|
||||||
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
|
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||||
|
|
|
@ -43,7 +43,7 @@ const uint8_t ff_aac_channel_layout_map[16][16][3] = {
|
||||||
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },
|
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },
|
||||||
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },
|
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },
|
||||||
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
|
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
|
||||||
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
|
{ { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },
|
||||||
{ { 0, } },
|
{ { 0, } },
|
||||||
{ { 0, } },
|
{ { 0, } },
|
||||||
{ { 0, } },
|
{ { 0, } },
|
||||||
|
|
|
@ -577,7 +577,7 @@ static ChannelElement *get_che(AACDecContext *ac, int type, int elem_id)
|
||||||
{
|
{
|
||||||
/* For PCE based channel configurations map the channels solely based
|
/* For PCE based channel configurations map the channels solely based
|
||||||
* on tags. */
|
* on tags. */
|
||||||
if (!ac->oc[1].m4ac.chan_config) {
|
if (!ac->oc[1].m4ac.chan_config || ac->oc[1].m4ac.pce) {
|
||||||
return ac->tag_che_map[type][elem_id];
|
return ac->tag_che_map[type][elem_id];
|
||||||
}
|
}
|
||||||
// Allow single CPE stereo files to be signalled with mono configuration.
|
// Allow single CPE stereo files to be signalled with mono configuration.
|
||||||
|
@ -3219,7 +3219,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, AVFrame *frame,
|
||||||
} else {
|
} else {
|
||||||
err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
|
err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
|
||||||
if (!err)
|
if (!err)
|
||||||
ac->oc[1].m4ac.chan_config = 0;
|
ac->oc[1].m4ac.pce = 1;
|
||||||
pce_found = 1;
|
pce_found = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,548 @@
|
||||||
|
/*
|
||||||
|
* AOM film grain synthesis
|
||||||
|
* Copyright (c) 2023 Niklas Haas <ffmpeg@haasn.xyz>
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* AOM film grain synthesis.
|
||||||
|
* @author Niklas Haas <ffmpeg@haasn.xyz>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libavutil/avassert.h"
|
||||||
|
#include "libavutil/imgutils.h"
|
||||||
|
|
||||||
|
#include "aom_film_grain.h"
|
||||||
|
#include "get_bits.h"
|
||||||
|
|
||||||
|
// Common/shared helpers (not dependent on BIT_DEPTH)
|
||||||
|
static inline int get_random_number(const int bits, unsigned *const state) {
|
||||||
|
const int r = *state;
|
||||||
|
unsigned bit = ((r >> 0) ^ (r >> 1) ^ (r >> 3) ^ (r >> 12)) & 1;
|
||||||
|
*state = (r >> 1) | (bit << 15);
|
||||||
|
|
||||||
|
return (*state >> (16 - bits)) & ((1 << bits) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int round2(const int x, const uint64_t shift) {
|
||||||
|
return (x + ((1 << shift) >> 1)) >> shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
GRAIN_WIDTH = 82,
|
||||||
|
GRAIN_HEIGHT = 73,
|
||||||
|
SUB_GRAIN_WIDTH = 44,
|
||||||
|
SUB_GRAIN_HEIGHT = 38,
|
||||||
|
FG_BLOCK_SIZE = 32,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int16_t gaussian_sequence[2048];
|
||||||
|
|
||||||
|
#define BIT_DEPTH 16
|
||||||
|
#include "aom_film_grain_template.c"
|
||||||
|
#undef BIT_DEPTH
|
||||||
|
|
||||||
|
#define BIT_DEPTH 8
|
||||||
|
#include "aom_film_grain_template.c"
|
||||||
|
#undef BIT_DEPTH
|
||||||
|
|
||||||
|
|
||||||
|
int ff_aom_apply_film_grain(AVFrame *out, const AVFrame *in,
|
||||||
|
const AVFilmGrainParams *params)
|
||||||
|
{
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(out->format);
|
||||||
|
const int subx = desc->log2_chroma_w, suby = desc->log2_chroma_h;
|
||||||
|
const int pxstep = desc->comp[0].step;
|
||||||
|
|
||||||
|
av_assert0(out->format == in->format);
|
||||||
|
av_assert0(params->type == AV_FILM_GRAIN_PARAMS_AV1);
|
||||||
|
|
||||||
|
// Copy over the non-modified planes
|
||||||
|
if (!params->codec.aom.num_y_points) {
|
||||||
|
av_image_copy_plane(out->data[0], out->linesize[0],
|
||||||
|
in->data[0], in->linesize[0],
|
||||||
|
out->width * pxstep, out->height);
|
||||||
|
}
|
||||||
|
for (int uv = 0; uv < 2; uv++) {
|
||||||
|
if (!data->num_uv_points[uv]) {
|
||||||
|
av_image_copy_plane(out->data[1+uv], out->linesize[1+uv],
|
||||||
|
in->data[1+uv], in->linesize[1+uv],
|
||||||
|
AV_CEIL_RSHIFT(out->width, subx) * pxstep,
|
||||||
|
AV_CEIL_RSHIFT(out->height, suby));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (in->format) {
|
||||||
|
case AV_PIX_FMT_GRAY8:
|
||||||
|
case AV_PIX_FMT_YUV420P:
|
||||||
|
case AV_PIX_FMT_YUV422P:
|
||||||
|
case AV_PIX_FMT_YUV444P:
|
||||||
|
case AV_PIX_FMT_YUVJ420P:
|
||||||
|
case AV_PIX_FMT_YUVJ422P:
|
||||||
|
case AV_PIX_FMT_YUVJ444P:
|
||||||
|
return apply_film_grain_8(out, in, params);
|
||||||
|
case AV_PIX_FMT_GRAY9:
|
||||||
|
case AV_PIX_FMT_YUV420P9:
|
||||||
|
case AV_PIX_FMT_YUV422P9:
|
||||||
|
case AV_PIX_FMT_YUV444P9:
|
||||||
|
return apply_film_grain_16(out, in, params, 9);
|
||||||
|
case AV_PIX_FMT_GRAY10:
|
||||||
|
case AV_PIX_FMT_YUV420P10:
|
||||||
|
case AV_PIX_FMT_YUV422P10:
|
||||||
|
case AV_PIX_FMT_YUV444P10:
|
||||||
|
return apply_film_grain_16(out, in, params, 10);
|
||||||
|
case AV_PIX_FMT_GRAY12:
|
||||||
|
case AV_PIX_FMT_YUV420P12:
|
||||||
|
case AV_PIX_FMT_YUV422P12:
|
||||||
|
case AV_PIX_FMT_YUV444P12:
|
||||||
|
return apply_film_grain_16(out, in, params, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The AV1 spec only defines film grain synthesis for these formats */
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s,
|
||||||
|
const uint8_t *payload, int payload_size)
|
||||||
|
{
|
||||||
|
GetBitContext gbc, *gb = &gbc;
|
||||||
|
AVFilmGrainAOMParams *aom;
|
||||||
|
AVFilmGrainParams *fgp, *ref = NULL;
|
||||||
|
int ret, num_sets, n, i, uv, num_y_coeffs, update_grain, luma_only;
|
||||||
|
|
||||||
|
ret = init_get_bits8(gb, payload, payload_size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
s->enable = get_bits1(gb);
|
||||||
|
if (!s->enable)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
skip_bits(gb, 4); // reserved
|
||||||
|
num_sets = get_bits(gb, 3) + 1;
|
||||||
|
for (n = 0; n < num_sets; n++) {
|
||||||
|
int payload_4byte, payload_size, set_idx, apply_units_log2, vsc_flag;
|
||||||
|
int predict_scaling, predict_y_scaling, predict_uv_scaling[2];
|
||||||
|
int payload_bits, start_position;
|
||||||
|
|
||||||
|
start_position = get_bits_count(gb);
|
||||||
|
payload_4byte = get_bits1(gb);
|
||||||
|
payload_size = get_bits(gb, payload_4byte ? 2 : 8);
|
||||||
|
set_idx = get_bits(gb, 3);
|
||||||
|
fgp = &s->sets[set_idx];
|
||||||
|
aom = &fgp->codec.aom;
|
||||||
|
|
||||||
|
fgp->type = get_bits1(gb) ? AV_FILM_GRAIN_PARAMS_AV1 : AV_FILM_GRAIN_PARAMS_NONE;
|
||||||
|
if (!fgp->type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fgp->seed = get_bits(gb, 16);
|
||||||
|
update_grain = get_bits1(gb);
|
||||||
|
if (!update_grain)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
apply_units_log2 = get_bits(gb, 4);
|
||||||
|
fgp->width = get_bits(gb, 12) << apply_units_log2;
|
||||||
|
fgp->height = get_bits(gb, 12) << apply_units_log2;
|
||||||
|
luma_only = get_bits1(gb);
|
||||||
|
if (luma_only) {
|
||||||
|
fgp->subsampling_x = fgp->subsampling_y = 0;
|
||||||
|
} else {
|
||||||
|
fgp->subsampling_x = get_bits1(gb);
|
||||||
|
fgp->subsampling_y = get_bits1(gb);
|
||||||
|
}
|
||||||
|
|
||||||
|
fgp->bit_depth_luma = fgp->bit_depth_chroma = 0;
|
||||||
|
fgp->color_primaries = AVCOL_PRI_UNSPECIFIED;
|
||||||
|
fgp->color_trc = AVCOL_TRC_UNSPECIFIED;
|
||||||
|
fgp->color_space = AVCOL_SPC_UNSPECIFIED;
|
||||||
|
fgp->color_range = AVCOL_RANGE_UNSPECIFIED;
|
||||||
|
|
||||||
|
vsc_flag = get_bits1(gb); // video_signal_characteristics_flag
|
||||||
|
if (vsc_flag) {
|
||||||
|
int cicp_flag;
|
||||||
|
fgp->bit_depth_luma = get_bits(gb, 3) + 8;
|
||||||
|
if (!luma_only)
|
||||||
|
fgp->bit_depth_chroma = fgp->bit_depth_luma;
|
||||||
|
cicp_flag = get_bits1(gb);
|
||||||
|
if (cicp_flag) {
|
||||||
|
fgp->color_primaries = get_bits(gb, 8);
|
||||||
|
fgp->color_trc = get_bits(gb, 8);
|
||||||
|
fgp->color_space = get_bits(gb, 8);
|
||||||
|
fgp->color_range = get_bits1(gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
|
||||||
|
if (fgp->color_primaries > AVCOL_PRI_NB ||
|
||||||
|
fgp->color_primaries == AVCOL_PRI_RESERVED ||
|
||||||
|
fgp->color_primaries == AVCOL_PRI_RESERVED0 ||
|
||||||
|
fgp->color_trc > AVCOL_TRC_NB ||
|
||||||
|
fgp->color_trc == AVCOL_TRC_RESERVED ||
|
||||||
|
fgp->color_trc == AVCOL_TRC_RESERVED0 ||
|
||||||
|
fgp->color_space > AVCOL_SPC_NB ||
|
||||||
|
fgp->color_space == AVCOL_SPC_RESERVED)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
predict_scaling = get_bits1(gb);
|
||||||
|
if (predict_scaling && (!ref || ref == fgp))
|
||||||
|
goto error; // prediction must be from valid, different set
|
||||||
|
|
||||||
|
predict_y_scaling = predict_scaling ? get_bits1(gb) : 0;
|
||||||
|
if (predict_y_scaling) {
|
||||||
|
int y_scale, y_offset, bits_res;
|
||||||
|
y_scale = get_bits(gb, 9) - 256;
|
||||||
|
y_offset = get_bits(gb, 9) - 256;
|
||||||
|
bits_res = get_bits(gb, 3);
|
||||||
|
if (bits_res) {
|
||||||
|
int res[14], pred, granularity;
|
||||||
|
aom->num_y_points = ref->codec.aom.num_y_points;
|
||||||
|
for (i = 0; i < aom->num_y_points; i++)
|
||||||
|
res[i] = get_bits(gb, bits_res);
|
||||||
|
granularity = get_bits(gb, 3);
|
||||||
|
for (i = 0; i < aom->num_y_points; i++) {
|
||||||
|
pred = ref->codec.aom.y_points[i][1];
|
||||||
|
pred = ((pred * y_scale + 8) >> 4) + y_offset;
|
||||||
|
pred += (res[i] - (1 << (bits_res - 1))) * granularity;
|
||||||
|
aom->y_points[i][0] = ref->codec.aom.y_points[i][0];
|
||||||
|
aom->y_points[i][1] = av_clip_uint8(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
aom->num_y_points = get_bits(gb, 4);
|
||||||
|
if (aom->num_y_points > 14) {
|
||||||
|
goto error;
|
||||||
|
} else if (aom->num_y_points) {
|
||||||
|
int bits_inc, bits_scaling;
|
||||||
|
int y_value = 0;
|
||||||
|
bits_inc = get_bits(gb, 3) + 1;
|
||||||
|
bits_scaling = get_bits(gb, 2) + 5;
|
||||||
|
for (i = 0; i < aom->num_y_points; i++) {
|
||||||
|
y_value += get_bits(gb, bits_inc);
|
||||||
|
if (y_value > UINT8_MAX)
|
||||||
|
goto error;
|
||||||
|
aom->y_points[i][0] = y_value;
|
||||||
|
aom->y_points[i][1] = get_bits(gb, bits_scaling);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (luma_only) {
|
||||||
|
aom->chroma_scaling_from_luma = 0;
|
||||||
|
aom->num_uv_points[0] = aom->num_uv_points[1] = 0;
|
||||||
|
} else {
|
||||||
|
aom->chroma_scaling_from_luma = get_bits1(gb);
|
||||||
|
if (aom->chroma_scaling_from_luma) {
|
||||||
|
aom->num_uv_points[0] = aom->num_uv_points[1] = 0;
|
||||||
|
} else {
|
||||||
|
for (uv = 0; uv < 2; uv++) {
|
||||||
|
predict_uv_scaling[uv] = predict_scaling ? get_bits1(gb) : 0;
|
||||||
|
if (predict_uv_scaling[uv]) {
|
||||||
|
int uv_scale, uv_offset, bits_res;
|
||||||
|
uv_scale = get_bits(gb, 9) - 256;
|
||||||
|
uv_offset = get_bits(gb, 9) - 256;
|
||||||
|
bits_res = get_bits(gb, 3);
|
||||||
|
aom->uv_mult[uv] = ref->codec.aom.uv_mult[uv];
|
||||||
|
aom->uv_mult_luma[uv] = ref->codec.aom.uv_mult_luma[uv];
|
||||||
|
aom->uv_offset[uv] = ref->codec.aom.uv_offset[uv];
|
||||||
|
if (bits_res) {
|
||||||
|
int res[10], pred, granularity;
|
||||||
|
aom->num_uv_points[uv] = ref->codec.aom.num_uv_points[uv];
|
||||||
|
for (i = 0; i < aom->num_uv_points[uv]; i++)
|
||||||
|
res[i] = get_bits(gb, bits_res);
|
||||||
|
granularity = get_bits(gb, 3);
|
||||||
|
for (i = 0; i < aom->num_uv_points[uv]; i++) {
|
||||||
|
pred = ref->codec.aom.uv_points[uv][i][1];
|
||||||
|
pred = ((pred * uv_scale + 8) >> 4) + uv_offset;
|
||||||
|
pred += (res[i] - (1 << (bits_res - 1))) * granularity;
|
||||||
|
aom->uv_points[uv][i][0] = ref->codec.aom.uv_points[uv][i][0];
|
||||||
|
aom->uv_points[uv][i][1] = av_clip_uint8(pred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int bits_inc, bits_scaling, uv_offset;
|
||||||
|
int uv_value = 0;
|
||||||
|
aom->num_uv_points[uv] = get_bits(gb, 4);
|
||||||
|
if (aom->num_uv_points[uv] > 10)
|
||||||
|
goto error;
|
||||||
|
bits_inc = get_bits(gb, 3) + 1;
|
||||||
|
bits_scaling = get_bits(gb, 2) + 5;
|
||||||
|
uv_offset = get_bits(gb, 8);
|
||||||
|
for (i = 0; i < aom->num_uv_points[uv]; i++) {
|
||||||
|
uv_value += get_bits(gb, bits_inc);
|
||||||
|
if (uv_value > UINT8_MAX)
|
||||||
|
goto error;
|
||||||
|
aom->uv_points[uv][i][0] = uv_value;
|
||||||
|
aom->uv_points[uv][i][1] = get_bits(gb, bits_scaling) + uv_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aom->scaling_shift = get_bits(gb, 2) + 8;
|
||||||
|
aom->ar_coeff_lag = get_bits(gb, 2);
|
||||||
|
num_y_coeffs = 2 * aom->ar_coeff_lag * (aom->ar_coeff_lag + 1);
|
||||||
|
if (aom->num_y_points) {
|
||||||
|
int ar_bits = get_bits(gb, 2) + 5;
|
||||||
|
for (i = 0; i < num_y_coeffs; i++)
|
||||||
|
aom->ar_coeffs_y[i] = get_bits(gb, ar_bits) - (1 << (ar_bits - 1));
|
||||||
|
}
|
||||||
|
for (uv = 0; uv < 2; uv++) {
|
||||||
|
if (aom->chroma_scaling_from_luma || aom->num_uv_points[uv]) {
|
||||||
|
int ar_bits = get_bits(gb, 2) + 5;
|
||||||
|
for (i = 0; i < num_y_coeffs + !!aom->num_y_points; i++)
|
||||||
|
aom->ar_coeffs_uv[uv][i] = get_bits(gb, ar_bits) - (1 << (ar_bits - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aom->ar_coeff_shift = get_bits(gb, 2) + 6;
|
||||||
|
aom->grain_scale_shift = get_bits(gb, 2);
|
||||||
|
for (uv = 0; uv < 2; uv++) {
|
||||||
|
if (aom->num_uv_points[uv] && !predict_uv_scaling[uv]) {
|
||||||
|
aom->uv_mult[uv] = get_bits(gb, 8) - 128;
|
||||||
|
aom->uv_mult_luma[uv] = get_bits(gb, 8) - 128;
|
||||||
|
aom->uv_offset[uv] = get_bits(gb, 9) - 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aom->overlap_flag = get_bits1(gb);
|
||||||
|
aom->limit_output_range = get_bits1(gb);
|
||||||
|
|
||||||
|
// use first set as reference only if it was fully transmitted
|
||||||
|
if (n == 0)
|
||||||
|
ref = fgp;
|
||||||
|
|
||||||
|
payload_bits = get_bits_count(gb) - start_position;
|
||||||
|
if (payload_bits > payload_size * 8)
|
||||||
|
goto error;
|
||||||
|
skip_bits(gb, payload_size * 8 - payload_bits);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
memset(s, 0, sizeof(*s));
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ff_aom_attach_film_grain_sets(const AVFilmGrainAFGS1Params *s, AVFrame *frame)
|
||||||
|
{
|
||||||
|
AVFilmGrainParams *fgp;
|
||||||
|
if (!s->enable)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < FF_ARRAY_ELEMS(s->sets); i++) {
|
||||||
|
if (s->sets[i].type != AV_FILM_GRAIN_PARAMS_AV1)
|
||||||
|
continue;
|
||||||
|
fgp = av_film_grain_params_create_side_data(frame);
|
||||||
|
if (!fgp)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
memcpy(fgp, &s->sets[i], sizeof(*fgp));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Taken from the AV1 spec. Range is [-2048, 2047], mean is 0 and stddev is 512
|
||||||
|
static const int16_t gaussian_sequence[2048] = {
|
||||||
|
56, 568, -180, 172, 124, -84, 172, -64, -900, 24, 820,
|
||||||
|
224, 1248, 996, 272, -8, -916, -388, -732, -104, -188, 800,
|
||||||
|
112, -652, -320, -376, 140, -252, 492, -168, 44, -788, 588,
|
||||||
|
-584, 500, -228, 12, 680, 272, -476, 972, -100, 652, 368,
|
||||||
|
432, -196, -720, -192, 1000, -332, 652, -136, -552, -604, -4,
|
||||||
|
192, -220, -136, 1000, -52, 372, -96, -624, 124, -24, 396,
|
||||||
|
540, -12, -104, 640, 464, 244, -208, -84, 368, -528, -740,
|
||||||
|
248, -968, -848, 608, 376, -60, -292, -40, -156, 252, -292,
|
||||||
|
248, 224, -280, 400, -244, 244, -60, 76, -80, 212, 532,
|
||||||
|
340, 128, -36, 824, -352, -60, -264, -96, -612, 416, -704,
|
||||||
|
220, -204, 640, -160, 1220, -408, 900, 336, 20, -336, -96,
|
||||||
|
-792, 304, 48, -28, -1232, -1172, -448, 104, -292, -520, 244,
|
||||||
|
60, -948, 0, -708, 268, 108, 356, -548, 488, -344, -136,
|
||||||
|
488, -196, -224, 656, -236, -1128, 60, 4, 140, 276, -676,
|
||||||
|
-376, 168, -108, 464, 8, 564, 64, 240, 308, -300, -400,
|
||||||
|
-456, -136, 56, 120, -408, -116, 436, 504, -232, 328, 844,
|
||||||
|
-164, -84, 784, -168, 232, -224, 348, -376, 128, 568, 96,
|
||||||
|
-1244, -288, 276, 848, 832, -360, 656, 464, -384, -332, -356,
|
||||||
|
728, -388, 160, -192, 468, 296, 224, 140, -776, -100, 280,
|
||||||
|
4, 196, 44, -36, -648, 932, 16, 1428, 28, 528, 808,
|
||||||
|
772, 20, 268, 88, -332, -284, 124, -384, -448, 208, -228,
|
||||||
|
-1044, -328, 660, 380, -148, -300, 588, 240, 540, 28, 136,
|
||||||
|
-88, -436, 256, 296, -1000, 1400, 0, -48, 1056, -136, 264,
|
||||||
|
-528, -1108, 632, -484, -592, -344, 796, 124, -668, -768, 388,
|
||||||
|
1296, -232, -188, -200, -288, -4, 308, 100, -168, 256, -500,
|
||||||
|
204, -508, 648, -136, 372, -272, -120, -1004, -552, -548, -384,
|
||||||
|
548, -296, 428, -108, -8, -912, -324, -224, -88, -112, -220,
|
||||||
|
-100, 996, -796, 548, 360, -216, 180, 428, -200, -212, 148,
|
||||||
|
96, 148, 284, 216, -412, -320, 120, -300, -384, -604, -572,
|
||||||
|
-332, -8, -180, -176, 696, 116, -88, 628, 76, 44, -516,
|
||||||
|
240, -208, -40, 100, -592, 344, -308, -452, -228, 20, 916,
|
||||||
|
-1752, -136, -340, -804, 140, 40, 512, 340, 248, 184, -492,
|
||||||
|
896, -156, 932, -628, 328, -688, -448, -616, -752, -100, 560,
|
||||||
|
-1020, 180, -800, -64, 76, 576, 1068, 396, 660, 552, -108,
|
||||||
|
-28, 320, -628, 312, -92, -92, -472, 268, 16, 560, 516,
|
||||||
|
-672, -52, 492, -100, 260, 384, 284, 292, 304, -148, 88,
|
||||||
|
-152, 1012, 1064, -228, 164, -376, -684, 592, -392, 156, 196,
|
||||||
|
-524, -64, -884, 160, -176, 636, 648, 404, -396, -436, 864,
|
||||||
|
424, -728, 988, -604, 904, -592, 296, -224, 536, -176, -920,
|
||||||
|
436, -48, 1176, -884, 416, -776, -824, -884, 524, -548, -564,
|
||||||
|
-68, -164, -96, 692, 364, -692, -1012, -68, 260, -480, 876,
|
||||||
|
-1116, 452, -332, -352, 892, -1088, 1220, -676, 12, -292, 244,
|
||||||
|
496, 372, -32, 280, 200, 112, -440, -96, 24, -644, -184,
|
||||||
|
56, -432, 224, -980, 272, -260, 144, -436, 420, 356, 364,
|
||||||
|
-528, 76, 172, -744, -368, 404, -752, -416, 684, -688, 72,
|
||||||
|
540, 416, 92, 444, 480, -72, -1416, 164, -1172, -68, 24,
|
||||||
|
424, 264, 1040, 128, -912, -524, -356, 64, 876, -12, 4,
|
||||||
|
-88, 532, 272, -524, 320, 276, -508, 940, 24, -400, -120,
|
||||||
|
756, 60, 236, -412, 100, 376, -484, 400, -100, -740, -108,
|
||||||
|
-260, 328, -268, 224, -200, -416, 184, -604, -564, -20, 296,
|
||||||
|
60, 892, -888, 60, 164, 68, -760, 216, -296, 904, -336,
|
||||||
|
-28, 404, -356, -568, -208, -1480, -512, 296, 328, -360, -164,
|
||||||
|
-1560, -776, 1156, -428, 164, -504, -112, 120, -216, -148, -264,
|
||||||
|
308, 32, 64, -72, 72, 116, 176, -64, -272, 460, -536,
|
||||||
|
-784, -280, 348, 108, -752, -132, 524, -540, -776, 116, -296,
|
||||||
|
-1196, -288, -560, 1040, -472, 116, -848, -1116, 116, 636, 696,
|
||||||
|
284, -176, 1016, 204, -864, -648, -248, 356, 972, -584, -204,
|
||||||
|
264, 880, 528, -24, -184, 116, 448, -144, 828, 524, 212,
|
||||||
|
-212, 52, 12, 200, 268, -488, -404, -880, 824, -672, -40,
|
||||||
|
908, -248, 500, 716, -576, 492, -576, 16, 720, -108, 384,
|
||||||
|
124, 344, 280, 576, -500, 252, 104, -308, 196, -188, -8,
|
||||||
|
1268, 296, 1032, -1196, 436, 316, 372, -432, -200, -660, 704,
|
||||||
|
-224, 596, -132, 268, 32, -452, 884, 104, -1008, 424, -1348,
|
||||||
|
-280, 4, -1168, 368, 476, 696, 300, -8, 24, 180, -592,
|
||||||
|
-196, 388, 304, 500, 724, -160, 244, -84, 272, -256, -420,
|
||||||
|
320, 208, -144, -156, 156, 364, 452, 28, 540, 316, 220,
|
||||||
|
-644, -248, 464, 72, 360, 32, -388, 496, -680, -48, 208,
|
||||||
|
-116, -408, 60, -604, -392, 548, -840, 784, -460, 656, -544,
|
||||||
|
-388, -264, 908, -800, -628, -612, -568, 572, -220, 164, 288,
|
||||||
|
-16, -308, 308, -112, -636, -760, 280, -668, 432, 364, 240,
|
||||||
|
-196, 604, 340, 384, 196, 592, -44, -500, 432, -580, -132,
|
||||||
|
636, -76, 392, 4, -412, 540, 508, 328, -356, -36, 16,
|
||||||
|
-220, -64, -248, -60, 24, -192, 368, 1040, 92, -24, -1044,
|
||||||
|
-32, 40, 104, 148, 192, -136, -520, 56, -816, -224, 732,
|
||||||
|
392, 356, 212, -80, -424, -1008, -324, 588, -1496, 576, 460,
|
||||||
|
-816, -848, 56, -580, -92, -1372, -112, -496, 200, 364, 52,
|
||||||
|
-140, 48, -48, -60, 84, 72, 40, 132, -356, -268, -104,
|
||||||
|
-284, -404, 732, -520, 164, -304, -540, 120, 328, -76, -460,
|
||||||
|
756, 388, 588, 236, -436, -72, -176, -404, -316, -148, 716,
|
||||||
|
-604, 404, -72, -88, -888, -68, 944, 88, -220, -344, 960,
|
||||||
|
472, 460, -232, 704, 120, 832, -228, 692, -508, 132, -476,
|
||||||
|
844, -748, -364, -44, 1116, -1104, -1056, 76, 428, 552, -692,
|
||||||
|
60, 356, 96, -384, -188, -612, -576, 736, 508, 892, 352,
|
||||||
|
-1132, 504, -24, -352, 324, 332, -600, -312, 292, 508, -144,
|
||||||
|
-8, 484, 48, 284, -260, -240, 256, -100, -292, -204, -44,
|
||||||
|
472, -204, 908, -188, -1000, -256, 92, 1164, -392, 564, 356,
|
||||||
|
652, -28, -884, 256, 484, -192, 760, -176, 376, -524, -452,
|
||||||
|
-436, 860, -736, 212, 124, 504, -476, 468, 76, -472, 552,
|
||||||
|
-692, -944, -620, 740, -240, 400, 132, 20, 192, -196, 264,
|
||||||
|
-668, -1012, -60, 296, -316, -828, 76, -156, 284, -768, -448,
|
||||||
|
-832, 148, 248, 652, 616, 1236, 288, -328, -400, -124, 588,
|
||||||
|
220, 520, -696, 1032, 768, -740, -92, -272, 296, 448, -464,
|
||||||
|
412, -200, 392, 440, -200, 264, -152, -260, 320, 1032, 216,
|
||||||
|
320, -8, -64, 156, -1016, 1084, 1172, 536, 484, -432, 132,
|
||||||
|
372, -52, -256, 84, 116, -352, 48, 116, 304, -384, 412,
|
||||||
|
924, -300, 528, 628, 180, 648, 44, -980, -220, 1320, 48,
|
||||||
|
332, 748, 524, -268, -720, 540, -276, 564, -344, -208, -196,
|
||||||
|
436, 896, 88, -392, 132, 80, -964, -288, 568, 56, -48,
|
||||||
|
-456, 888, 8, 552, -156, -292, 948, 288, 128, -716, -292,
|
||||||
|
1192, -152, 876, 352, -600, -260, -812, -468, -28, -120, -32,
|
||||||
|
-44, 1284, 496, 192, 464, 312, -76, -516, -380, -456, -1012,
|
||||||
|
-48, 308, -156, 36, 492, -156, -808, 188, 1652, 68, -120,
|
||||||
|
-116, 316, 160, -140, 352, 808, -416, 592, 316, -480, 56,
|
||||||
|
528, -204, -568, 372, -232, 752, -344, 744, -4, 324, -416,
|
||||||
|
-600, 768, 268, -248, -88, -132, -420, -432, 80, -288, 404,
|
||||||
|
-316, -1216, -588, 520, -108, 92, -320, 368, -480, -216, -92,
|
||||||
|
1688, -300, 180, 1020, -176, 820, -68, -228, -260, 436, -904,
|
||||||
|
20, 40, -508, 440, -736, 312, 332, 204, 760, -372, 728,
|
||||||
|
96, -20, -632, -520, -560, 336, 1076, -64, -532, 776, 584,
|
||||||
|
192, 396, -728, -520, 276, -188, 80, -52, -612, -252, -48,
|
||||||
|
648, 212, -688, 228, -52, -260, 428, -412, -272, -404, 180,
|
||||||
|
816, -796, 48, 152, 484, -88, -216, 988, 696, 188, -528,
|
||||||
|
648, -116, -180, 316, 476, 12, -564, 96, 476, -252, -364,
|
||||||
|
-376, -392, 556, -256, -576, 260, -352, 120, -16, -136, -260,
|
||||||
|
-492, 72, 556, 660, 580, 616, 772, 436, 424, -32, -324,
|
||||||
|
-1268, 416, -324, -80, 920, 160, 228, 724, 32, -516, 64,
|
||||||
|
384, 68, -128, 136, 240, 248, -204, -68, 252, -932, -120,
|
||||||
|
-480, -628, -84, 192, 852, -404, -288, -132, 204, 100, 168,
|
||||||
|
-68, -196, -868, 460, 1080, 380, -80, 244, 0, 484, -888,
|
||||||
|
64, 184, 352, 600, 460, 164, 604, -196, 320, -64, 588,
|
||||||
|
-184, 228, 12, 372, 48, -848, -344, 224, 208, -200, 484,
|
||||||
|
128, -20, 272, -468, -840, 384, 256, -720, -520, -464, -580,
|
||||||
|
112, -120, 644, -356, -208, -608, -528, 704, 560, -424, 392,
|
||||||
|
828, 40, 84, 200, -152, 0, -144, 584, 280, -120, 80,
|
||||||
|
-556, -972, -196, -472, 724, 80, 168, -32, 88, 160, -688,
|
||||||
|
0, 160, 356, 372, -776, 740, -128, 676, -248, -480, 4,
|
||||||
|
-364, 96, 544, 232, -1032, 956, 236, 356, 20, -40, 300,
|
||||||
|
24, -676, -596, 132, 1120, -104, 532, -1096, 568, 648, 444,
|
||||||
|
508, 380, 188, -376, -604, 1488, 424, 24, 756, -220, -192,
|
||||||
|
716, 120, 920, 688, 168, 44, -460, 568, 284, 1144, 1160,
|
||||||
|
600, 424, 888, 656, -356, -320, 220, 316, -176, -724, -188,
|
||||||
|
-816, -628, -348, -228, -380, 1012, -452, -660, 736, 928, 404,
|
||||||
|
-696, -72, -268, -892, 128, 184, -344, -780, 360, 336, 400,
|
||||||
|
344, 428, 548, -112, 136, -228, -216, -820, -516, 340, 92,
|
||||||
|
-136, 116, -300, 376, -244, 100, -316, -520, -284, -12, 824,
|
||||||
|
164, -548, -180, -128, 116, -924, -828, 268, -368, -580, 620,
|
||||||
|
192, 160, 0, -1676, 1068, 424, -56, -360, 468, -156, 720,
|
||||||
|
288, -528, 556, -364, 548, -148, 504, 316, 152, -648, -620,
|
||||||
|
-684, -24, -376, -384, -108, -920, -1032, 768, 180, -264, -508,
|
||||||
|
-1268, -260, -60, 300, -240, 988, 724, -376, -576, -212, -736,
|
||||||
|
556, 192, 1092, -620, -880, 376, -56, -4, -216, -32, 836,
|
||||||
|
268, 396, 1332, 864, -600, 100, 56, -412, -92, 356, 180,
|
||||||
|
884, -468, -436, 292, -388, -804, -704, -840, 368, -348, 140,
|
||||||
|
-724, 1536, 940, 372, 112, -372, 436, -480, 1136, 296, -32,
|
||||||
|
-228, 132, -48, -220, 868, -1016, -60, -1044, -464, 328, 916,
|
||||||
|
244, 12, -736, -296, 360, 468, -376, -108, -92, 788, 368,
|
||||||
|
-56, 544, 400, -672, -420, 728, 16, 320, 44, -284, -380,
|
||||||
|
-796, 488, 132, 204, -596, -372, 88, -152, -908, -636, -572,
|
||||||
|
-624, -116, -692, -200, -56, 276, -88, 484, -324, 948, 864,
|
||||||
|
1000, -456, -184, -276, 292, -296, 156, 676, 320, 160, 908,
|
||||||
|
-84, -1236, -288, -116, 260, -372, -644, 732, -756, -96, 84,
|
||||||
|
344, -520, 348, -688, 240, -84, 216, -1044, -136, -676, -396,
|
||||||
|
-1500, 960, -40, 176, 168, 1516, 420, -504, -344, -364, -360,
|
||||||
|
1216, -940, -380, -212, 252, -660, -708, 484, -444, -152, 928,
|
||||||
|
-120, 1112, 476, -260, 560, -148, -344, 108, -196, 228, -288,
|
||||||
|
504, 560, -328, -88, 288, -1008, 460, -228, 468, -836, -196,
|
||||||
|
76, 388, 232, 412, -1168, -716, -644, 756, -172, -356, -504,
|
||||||
|
116, 432, 528, 48, 476, -168, -608, 448, 160, -532, -272,
|
||||||
|
28, -676, -12, 828, 980, 456, 520, 104, -104, 256, -344,
|
||||||
|
-4, -28, -368, -52, -524, -572, -556, -200, 768, 1124, -208,
|
||||||
|
-512, 176, 232, 248, -148, -888, 604, -600, -304, 804, -156,
|
||||||
|
-212, 488, -192, -804, -256, 368, -360, -916, -328, 228, -240,
|
||||||
|
-448, -472, 856, -556, -364, 572, -12, -156, -368, -340, 432,
|
||||||
|
252, -752, -152, 288, 268, -580, -848, -592, 108, -76, 244,
|
||||||
|
312, -716, 592, -80, 436, 360, 4, -248, 160, 516, 584,
|
||||||
|
732, 44, -468, -280, -292, -156, -588, 28, 308, 912, 24,
|
||||||
|
124, 156, 180, -252, 944, -924, -772, -520, -428, -624, 300,
|
||||||
|
-212, -1144, 32, -724, 800, -1128, -212, -1288, -848, 180, -416,
|
||||||
|
440, 192, -576, -792, -76, -1080, 80, -532, -352, -132, 380,
|
||||||
|
-820, 148, 1112, 128, 164, 456, 700, -924, 144, -668, -384,
|
||||||
|
648, -832, 508, 552, -52, -100, -656, 208, -568, 748, -88,
|
||||||
|
680, 232, 300, 192, -408, -1012, -152, -252, -268, 272, -876,
|
||||||
|
-664, -648, -332, -136, 16, 12, 1152, -28, 332, -536, 320,
|
||||||
|
-672, -460, -316, 532, -260, 228, -40, 1052, -816, 180, 88,
|
||||||
|
-496, -556, -672, -368, 428, 92, 356, 404, -408, 252, 196,
|
||||||
|
-176, -556, 792, 268, 32, 372, 40, 96, -332, 328, 120,
|
||||||
|
372, -900, -40, 472, -264, -592, 952, 128, 656, 112, 664,
|
||||||
|
-232, 420, 4, -344, -464, 556, 244, -416, -32, 252, 0,
|
||||||
|
-412, 188, -696, 508, -476, 324, -1096, 656, -312, 560, 264,
|
||||||
|
-136, 304, 160, -64, -580, 248, 336, -720, 560, -348, -288,
|
||||||
|
-276, -196, -500, 852, -544, -236, -1128, -992, -776, 116, 56,
|
||||||
|
52, 860, 884, 212, -12, 168, 1020, 512, -552, 924, -148,
|
||||||
|
716, 188, 164, -340, -520, -184, 880, -152, -680, -208, -1156,
|
||||||
|
-300, -528, -472, 364, 100, -744, -1056, -32, 540, 280, 144,
|
||||||
|
-676, -32, -232, -280, -224, 96, 568, -76, 172, 148, 148,
|
||||||
|
104, 32, -296, -32, 788, -80, 32, -16, 280, 288, 944,
|
||||||
|
428, -484
|
||||||
|
};
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* AOM film grain synthesis
|
||||||
|
* Copyright (c) 2021 Niklas Haas <ffmpeg@haasn.xyz>
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* AOM film grain synthesis.
|
||||||
|
* @author Niklas Haas <ffmpeg@haasn.xyz>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVCODEC_AOM_FILM_GRAIN_H
|
||||||
|
#define AVCODEC_AOM_FILM_GRAIN_H
|
||||||
|
|
||||||
|
#include "libavutil/film_grain_params.h"
|
||||||
|
|
||||||
|
typedef struct AVFilmGrainAFGS1Params {
|
||||||
|
int enable;
|
||||||
|
AVFilmGrainParams sets[8];
|
||||||
|
} AVFilmGrainAFGS1Params;
|
||||||
|
|
||||||
|
// Synthesizes film grain on top of `in` and stores the result to `out`. `out`
|
||||||
|
// must already have been allocated and set to the same size and format as `in`.
|
||||||
|
int ff_aom_apply_film_grain(AVFrame *out, const AVFrame *in,
|
||||||
|
const AVFilmGrainParams *params);
|
||||||
|
|
||||||
|
// Parse AFGS1 parameter sets from an ITU-T T.35 payload. Returns 0 on success,
|
||||||
|
// or a negative error code.
|
||||||
|
int ff_aom_parse_film_grain_sets(AVFilmGrainAFGS1Params *s,
|
||||||
|
const uint8_t *payload, int payload_size);
|
||||||
|
|
||||||
|
// Attach all valid film grain param sets to `frame`.
|
||||||
|
int ff_aom_attach_film_grain_sets(const AVFilmGrainAFGS1Params *s, AVFrame *frame);
|
||||||
|
|
||||||
|
#endif /* AVCODEC_AOM_FILM_GRAIN_H */
|
|
@ -0,0 +1,577 @@
|
||||||
|
/*
|
||||||
|
* AOM film grain synthesis
|
||||||
|
* Copyright (c) 2023 Niklas Haas <ffmpeg@haasn.xyz>
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2018, Niklas Haas
|
||||||
|
* Copyright © 2018, VideoLAN and dav1d authors
|
||||||
|
* Copyright © 2018, Two Orioles, LLC
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bit_depth_template.c"
|
||||||
|
|
||||||
|
#undef entry
|
||||||
|
#undef bitdepth
|
||||||
|
#undef bitdepth_max
|
||||||
|
#undef HBD_DECL
|
||||||
|
#undef HBD_CALL
|
||||||
|
#undef SCALING_SIZE
|
||||||
|
|
||||||
|
#if BIT_DEPTH > 8
|
||||||
|
# define entry int16_t
|
||||||
|
# define bitdepth_max ((1 << bitdepth) - 1)
|
||||||
|
# define HBD_DECL , const int bitdepth
|
||||||
|
# define HBD_CALL , bitdepth
|
||||||
|
# define SCALING_SIZE 4096
|
||||||
|
#else
|
||||||
|
# define entry int8_t
|
||||||
|
# define bitdepth 8
|
||||||
|
# define bitdepth_max UINT8_MAX
|
||||||
|
# define HBD_DECL
|
||||||
|
# define HBD_CALL
|
||||||
|
# define SCALING_SIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void FUNC(generate_grain_y_c)(entry buf[][GRAIN_WIDTH],
|
||||||
|
const AVFilmGrainParams *const params
|
||||||
|
HBD_DECL)
|
||||||
|
{
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const int bitdepth_min_8 = bitdepth - 8;
|
||||||
|
unsigned seed = params->seed;
|
||||||
|
const int shift = 4 - bitdepth_min_8 + data->grain_scale_shift;
|
||||||
|
const int grain_ctr = 128 << bitdepth_min_8;
|
||||||
|
const int grain_min = -grain_ctr, grain_max = grain_ctr - 1;
|
||||||
|
|
||||||
|
const int ar_pad = 3;
|
||||||
|
const int ar_lag = data->ar_coeff_lag;
|
||||||
|
|
||||||
|
for (int y = 0; y < GRAIN_HEIGHT; y++) {
|
||||||
|
for (int x = 0; x < GRAIN_WIDTH; x++) {
|
||||||
|
const int value = get_random_number(11, &seed);
|
||||||
|
buf[y][x] = round2(gaussian_sequence[ value ], shift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = ar_pad; y < GRAIN_HEIGHT; y++) {
|
||||||
|
for (int x = ar_pad; x < GRAIN_WIDTH - ar_pad; x++) {
|
||||||
|
const int8_t *coeff = data->ar_coeffs_y;
|
||||||
|
int sum = 0, grain;
|
||||||
|
for (int dy = -ar_lag; dy <= 0; dy++) {
|
||||||
|
for (int dx = -ar_lag; dx <= ar_lag; dx++) {
|
||||||
|
if (!dx && !dy)
|
||||||
|
break;
|
||||||
|
sum += *(coeff++) * buf[y + dy][x + dx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grain = buf[y][x] + round2(sum, data->ar_coeff_shift);
|
||||||
|
buf[y][x] = av_clip(grain, grain_min, grain_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FUNC(generate_grain_uv_c)(entry buf[][GRAIN_WIDTH],
|
||||||
|
const entry buf_y[][GRAIN_WIDTH],
|
||||||
|
const AVFilmGrainParams *const params, const intptr_t uv,
|
||||||
|
const int subx, const int suby HBD_DECL)
|
||||||
|
{
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const int bitdepth_min_8 = bitdepth - 8;
|
||||||
|
unsigned seed = params->seed ^ (uv ? 0x49d8 : 0xb524);
|
||||||
|
const int shift = 4 - bitdepth_min_8 + data->grain_scale_shift;
|
||||||
|
const int grain_ctr = 128 << bitdepth_min_8;
|
||||||
|
const int grain_min = -grain_ctr, grain_max = grain_ctr - 1;
|
||||||
|
|
||||||
|
const int chromaW = subx ? SUB_GRAIN_WIDTH : GRAIN_WIDTH;
|
||||||
|
const int chromaH = suby ? SUB_GRAIN_HEIGHT : GRAIN_HEIGHT;
|
||||||
|
|
||||||
|
const int ar_pad = 3;
|
||||||
|
const int ar_lag = data->ar_coeff_lag;
|
||||||
|
|
||||||
|
for (int y = 0; y < chromaH; y++) {
|
||||||
|
for (int x = 0; x < chromaW; x++) {
|
||||||
|
const int value = get_random_number(11, &seed);
|
||||||
|
buf[y][x] = round2(gaussian_sequence[ value ], shift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = ar_pad; y < chromaH; y++) {
|
||||||
|
for (int x = ar_pad; x < chromaW - ar_pad; x++) {
|
||||||
|
const int8_t *coeff = data->ar_coeffs_uv[uv];
|
||||||
|
int sum = 0, grain;
|
||||||
|
for (int dy = -ar_lag; dy <= 0; dy++) {
|
||||||
|
for (int dx = -ar_lag; dx <= ar_lag; dx++) {
|
||||||
|
// For the final (current) pixel, we need to add in the
|
||||||
|
// contribution from the luma grain texture
|
||||||
|
if (!dx && !dy) {
|
||||||
|
const int lumaX = ((x - ar_pad) << subx) + ar_pad;
|
||||||
|
const int lumaY = ((y - ar_pad) << suby) + ar_pad;
|
||||||
|
int luma = 0;
|
||||||
|
if (!data->num_y_points)
|
||||||
|
break;
|
||||||
|
for (int i = 0; i <= suby; i++) {
|
||||||
|
for (int j = 0; j <= subx; j++) {
|
||||||
|
luma += buf_y[lumaY + i][lumaX + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
luma = round2(luma, subx + suby);
|
||||||
|
sum += luma * (*coeff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum += *(coeff++) * buf[y + dy][x + dx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grain = buf[y][x] + round2(sum, data->ar_coeff_shift);
|
||||||
|
buf[y][x] = av_clip(grain, grain_min, grain_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// samples from the correct block of a grain LUT, while taking into account the
|
||||||
|
// offsets provided by the offsets cache
|
||||||
|
static inline entry FUNC(sample_lut)(const entry grain_lut[][GRAIN_WIDTH],
|
||||||
|
const int offsets[2][2],
|
||||||
|
const int subx, const int suby,
|
||||||
|
const int bx, const int by,
|
||||||
|
const int x, const int y)
|
||||||
|
{
|
||||||
|
const int randval = offsets[bx][by];
|
||||||
|
const int offx = 3 + (2 >> subx) * (3 + (randval >> 4));
|
||||||
|
const int offy = 3 + (2 >> suby) * (3 + (randval & 0xF));
|
||||||
|
return grain_lut[offy + y + (FG_BLOCK_SIZE >> suby) * by]
|
||||||
|
[offx + x + (FG_BLOCK_SIZE >> subx) * bx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FUNC(fgy_32x32xn_c)(pixel *const dst_row, const pixel *const src_row,
|
||||||
|
const ptrdiff_t stride,
|
||||||
|
const AVFilmGrainParams *const params, const size_t pw,
|
||||||
|
const uint8_t scaling[SCALING_SIZE],
|
||||||
|
const entry grain_lut[][GRAIN_WIDTH],
|
||||||
|
const int bh, const int row_num HBD_DECL)
|
||||||
|
{
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const int rows = 1 + (data->overlap_flag && row_num > 0);
|
||||||
|
const int bitdepth_min_8 = bitdepth - 8;
|
||||||
|
const int grain_ctr = 128 << bitdepth_min_8;
|
||||||
|
const int grain_min = -grain_ctr, grain_max = grain_ctr - 1;
|
||||||
|
unsigned seed[2];
|
||||||
|
int offsets[2 /* col offset */][2 /* row offset */];
|
||||||
|
|
||||||
|
int min_value, max_value;
|
||||||
|
if (data->limit_output_range) {
|
||||||
|
min_value = 16 << bitdepth_min_8;
|
||||||
|
max_value = 235 << bitdepth_min_8;
|
||||||
|
} else {
|
||||||
|
min_value = 0;
|
||||||
|
max_value = bitdepth_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// seed[0] contains the current row, seed[1] contains the previous
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
seed[i] = params->seed;
|
||||||
|
seed[i] ^= (((row_num - i) * 37 + 178) & 0xFF) << 8;
|
||||||
|
seed[i] ^= (((row_num - i) * 173 + 105) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
av_assert1(stride % (FG_BLOCK_SIZE * sizeof(pixel)) == 0);
|
||||||
|
|
||||||
|
// process this row in FG_BLOCK_SIZE^2 blocks
|
||||||
|
for (unsigned bx = 0; bx < pw; bx += FG_BLOCK_SIZE) {
|
||||||
|
const int bw = FFMIN(FG_BLOCK_SIZE, (int) pw - bx);
|
||||||
|
const pixel *src;
|
||||||
|
pixel *dst;
|
||||||
|
int noise;
|
||||||
|
|
||||||
|
// x/y block offsets to compensate for overlapped regions
|
||||||
|
const int ystart = data->overlap_flag && row_num ? FFMIN(2, bh) : 0;
|
||||||
|
const int xstart = data->overlap_flag && bx ? FFMIN(2, bw) : 0;
|
||||||
|
|
||||||
|
static const int w[2][2] = { { 27, 17 }, { 17, 27 } };
|
||||||
|
|
||||||
|
if (data->overlap_flag && bx) {
|
||||||
|
// shift previous offsets left
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
offsets[1][i] = offsets[0][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// update current offsets
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
offsets[0][i] = get_random_number(8, &seed[i]);
|
||||||
|
|
||||||
|
#define add_noise_y(x, y, grain) \
|
||||||
|
src = (const pixel*)((const char*)src_row + (y) * stride) + (x) + bx; \
|
||||||
|
dst = (pixel*)((char*)dst_row + (y) * stride) + (x) + bx; \
|
||||||
|
noise = round2(scaling[ *src ] * (grain), data->scaling_shift); \
|
||||||
|
*dst = av_clip(*src + noise, min_value, max_value);
|
||||||
|
|
||||||
|
for (int y = ystart; y < bh; y++) {
|
||||||
|
// Non-overlapped image region (straightforward)
|
||||||
|
for (int x = xstart; x < bw; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 0, 0, x, y);
|
||||||
|
add_noise_y(x, y, grain);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for overlapped column
|
||||||
|
for (int x = 0; x < xstart; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 0, 0, x, y);
|
||||||
|
int old = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 1, 0, x, y);
|
||||||
|
grain = round2(old * w[x][0] + grain * w[x][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
add_noise_y(x, y, grain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < ystart; y++) {
|
||||||
|
// Special case for overlapped row (sans corner)
|
||||||
|
for (int x = xstart; x < bw; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 0, 0, x, y);
|
||||||
|
int old = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 0, 1, x, y);
|
||||||
|
grain = round2(old * w[y][0] + grain * w[y][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
add_noise_y(x, y, grain);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for doubly-overlapped corner
|
||||||
|
for (int x = 0; x < xstart; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 0, 0, x, y);
|
||||||
|
int top = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 0, 1, x, y);
|
||||||
|
int old = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 1, 1, x, y);
|
||||||
|
|
||||||
|
// Blend the top pixel with the top left block
|
||||||
|
top = round2(old * w[x][0] + top * w[x][1], 5);
|
||||||
|
top = av_clip(top, grain_min, grain_max);
|
||||||
|
|
||||||
|
// Blend the current pixel with the left block
|
||||||
|
old = FUNC(sample_lut)(grain_lut, offsets, 0, 0, 1, 0, x, y);
|
||||||
|
grain = round2(old * w[x][0] + grain * w[x][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
|
||||||
|
// Mix the row rows together and apply grain
|
||||||
|
grain = round2(top * w[y][0] + grain * w[y][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
add_noise_y(x, y, grain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
FUNC(fguv_32x32xn_c)(pixel *const dst_row, const pixel *const src_row,
|
||||||
|
const ptrdiff_t stride, const AVFilmGrainParams *const params,
|
||||||
|
const size_t pw, const uint8_t scaling[SCALING_SIZE],
|
||||||
|
const entry grain_lut[][GRAIN_WIDTH], const int bh,
|
||||||
|
const int row_num, const pixel *const luma_row,
|
||||||
|
const ptrdiff_t luma_stride, const int uv, const int is_id,
|
||||||
|
const int sx, const int sy HBD_DECL)
|
||||||
|
{
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const int rows = 1 + (data->overlap_flag && row_num > 0);
|
||||||
|
const int bitdepth_min_8 = bitdepth - 8;
|
||||||
|
const int grain_ctr = 128 << bitdepth_min_8;
|
||||||
|
const int grain_min = -grain_ctr, grain_max = grain_ctr - 1;
|
||||||
|
unsigned seed[2];
|
||||||
|
int offsets[2 /* col offset */][2 /* row offset */];
|
||||||
|
|
||||||
|
int min_value, max_value;
|
||||||
|
if (data->limit_output_range) {
|
||||||
|
min_value = 16 << bitdepth_min_8;
|
||||||
|
max_value = (is_id ? 235 : 240) << bitdepth_min_8;
|
||||||
|
} else {
|
||||||
|
min_value = 0;
|
||||||
|
max_value = bitdepth_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// seed[0] contains the current row, seed[1] contains the previous
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
seed[i] = params->seed;
|
||||||
|
seed[i] ^= (((row_num - i) * 37 + 178) & 0xFF) << 8;
|
||||||
|
seed[i] ^= (((row_num - i) * 173 + 105) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
av_assert1(stride % (FG_BLOCK_SIZE * sizeof(pixel)) == 0);
|
||||||
|
|
||||||
|
// process this row in FG_BLOCK_SIZE^2 blocks (subsampled)
|
||||||
|
for (unsigned bx = 0; bx < pw; bx += FG_BLOCK_SIZE >> sx) {
|
||||||
|
const int bw = FFMIN(FG_BLOCK_SIZE >> sx, (int)(pw - bx));
|
||||||
|
int val, lx, ly, noise;
|
||||||
|
const pixel *src, *luma;
|
||||||
|
pixel *dst, avg;
|
||||||
|
|
||||||
|
// x/y block offsets to compensate for overlapped regions
|
||||||
|
const int ystart = data->overlap_flag && row_num ? FFMIN(2 >> sy, bh) : 0;
|
||||||
|
const int xstart = data->overlap_flag && bx ? FFMIN(2 >> sx, bw) : 0;
|
||||||
|
|
||||||
|
static const int w[2 /* sub */][2 /* off */][2] = {
|
||||||
|
{ { 27, 17 }, { 17, 27 } },
|
||||||
|
{ { 23, 22 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data->overlap_flag && bx) {
|
||||||
|
// shift previous offsets left
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
offsets[1][i] = offsets[0][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// update current offsets
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
offsets[0][i] = get_random_number(8, &seed[i]);
|
||||||
|
|
||||||
|
#define add_noise_uv(x, y, grain) \
|
||||||
|
lx = (bx + x) << sx; \
|
||||||
|
ly = y << sy; \
|
||||||
|
luma = (const pixel*)((const char*)luma_row + ly * luma_stride) + lx;\
|
||||||
|
avg = luma[0]; \
|
||||||
|
if (sx) \
|
||||||
|
avg = (avg + luma[1] + 1) >> 1; \
|
||||||
|
src = (const pixel*)((const char *)src_row + (y) * stride) + bx + (x);\
|
||||||
|
dst = (pixel *) ((char *) dst_row + (y) * stride) + bx + (x); \
|
||||||
|
val = avg; \
|
||||||
|
if (!data->chroma_scaling_from_luma) { \
|
||||||
|
const int combined = avg * data->uv_mult_luma[uv] + \
|
||||||
|
*src * data->uv_mult[uv]; \
|
||||||
|
val = av_clip( (combined >> 6) + \
|
||||||
|
(data->uv_offset[uv] * (1 << bitdepth_min_8)), \
|
||||||
|
0, bitdepth_max ); \
|
||||||
|
} \
|
||||||
|
noise = round2(scaling[ val ] * (grain), data->scaling_shift); \
|
||||||
|
*dst = av_clip(*src + noise, min_value, max_value);
|
||||||
|
|
||||||
|
for (int y = ystart; y < bh; y++) {
|
||||||
|
// Non-overlapped image region (straightforward)
|
||||||
|
for (int x = xstart; x < bw; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 0, 0, x, y);
|
||||||
|
add_noise_uv(x, y, grain);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for overlapped column
|
||||||
|
for (int x = 0; x < xstart; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 0, 0, x, y);
|
||||||
|
int old = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 1, 0, x, y);
|
||||||
|
grain = round2(old * w[sx][x][0] + grain * w[sx][x][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
add_noise_uv(x, y, grain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < ystart; y++) {
|
||||||
|
// Special case for overlapped row (sans corner)
|
||||||
|
for (int x = xstart; x < bw; x++) {
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 0, 0, x, y);
|
||||||
|
int old = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 0, 1, x, y);
|
||||||
|
grain = round2(old * w[sy][y][0] + grain * w[sy][y][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
add_noise_uv(x, y, grain);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for doubly-overlapped corner
|
||||||
|
for (int x = 0; x < xstart; x++) {
|
||||||
|
int top = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 0, 1, x, y);
|
||||||
|
int old = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 1, 1, x, y);
|
||||||
|
int grain = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 0, 0, x, y);
|
||||||
|
|
||||||
|
// Blend the top pixel with the top left block
|
||||||
|
top = round2(old * w[sx][x][0] + top * w[sx][x][1], 5);
|
||||||
|
top = av_clip(top, grain_min, grain_max);
|
||||||
|
|
||||||
|
// Blend the current pixel with the left block
|
||||||
|
old = FUNC(sample_lut)(grain_lut, offsets, sx, sy, 1, 0, x, y);
|
||||||
|
grain = round2(old * w[sx][x][0] + grain * w[sx][x][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
|
||||||
|
// Mix the row rows together and apply to image
|
||||||
|
grain = round2(top * w[sy][y][0] + grain * w[sy][y][1], 5);
|
||||||
|
grain = av_clip(grain, grain_min, grain_max);
|
||||||
|
add_noise_uv(x, y, grain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FUNC(generate_scaling)(const uint8_t points[][2], const int num,
|
||||||
|
uint8_t scaling[SCALING_SIZE] HBD_DECL)
|
||||||
|
{
|
||||||
|
const int shift_x = bitdepth - 8;
|
||||||
|
const int scaling_size = 1 << bitdepth;
|
||||||
|
const int max_value = points[num - 1][0] << shift_x;
|
||||||
|
av_assert0(scaling_size <= SCALING_SIZE);
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
memset(scaling, 0, scaling_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill up the preceding entries with the initial value
|
||||||
|
memset(scaling, points[0][1], points[0][0] << shift_x);
|
||||||
|
|
||||||
|
// Linearly interpolate the values in the middle
|
||||||
|
for (int i = 0; i < num - 1; i++) {
|
||||||
|
const int bx = points[i][0];
|
||||||
|
const int by = points[i][1];
|
||||||
|
const int ex = points[i+1][0];
|
||||||
|
const int ey = points[i+1][1];
|
||||||
|
const int dx = ex - bx;
|
||||||
|
const int dy = ey - by;
|
||||||
|
const int delta = dy * ((0x10000 + (dx >> 1)) / dx);
|
||||||
|
av_assert1(dx > 0);
|
||||||
|
for (int x = 0, d = 0x8000; x < dx; x++) {
|
||||||
|
scaling[(bx + x) << shift_x] = by + (d >> 16);
|
||||||
|
d += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill up the remaining entries with the final value
|
||||||
|
memset(&scaling[max_value], points[num - 1][1], scaling_size - max_value);
|
||||||
|
|
||||||
|
#if BIT_DEPTH != 8
|
||||||
|
for (int i = 0; i < num - 1; i++) {
|
||||||
|
const int pad = 1 << shift_x, rnd = pad >> 1;
|
||||||
|
const int bx = points[i][0] << shift_x;
|
||||||
|
const int ex = points[i+1][0] << shift_x;
|
||||||
|
const int dx = ex - bx;
|
||||||
|
for (int x = 0; x < dx; x += pad) {
|
||||||
|
const int range = scaling[bx + x + pad] - scaling[bx + x];
|
||||||
|
for (int n = 1, r = rnd; n < pad; n++) {
|
||||||
|
r += range;
|
||||||
|
scaling[bx + x + n] = scaling[bx + x] + (r >> shift_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_always_inline void
|
||||||
|
FUNC(apply_grain_row)(AVFrame *out, const AVFrame *in,
|
||||||
|
const int ss_x, const int ss_y,
|
||||||
|
const uint8_t scaling[3][SCALING_SIZE],
|
||||||
|
const entry grain_lut[3][GRAIN_HEIGHT+1][GRAIN_WIDTH],
|
||||||
|
const AVFilmGrainParams *params,
|
||||||
|
const int row HBD_DECL)
|
||||||
|
{
|
||||||
|
// Synthesize grain for the affected planes
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const int cpw = (out->width + ss_x) >> ss_x;
|
||||||
|
const int is_id = out->colorspace == AVCOL_SPC_RGB;
|
||||||
|
const int bh = (FFMIN(out->height - row * FG_BLOCK_SIZE, FG_BLOCK_SIZE) + ss_y) >> ss_y;
|
||||||
|
const ptrdiff_t uv_off = row * FG_BLOCK_SIZE * out->linesize[1] >> ss_y;
|
||||||
|
pixel *const luma_src = (pixel *)
|
||||||
|
((char *) in->data[0] + row * FG_BLOCK_SIZE * in->linesize[0]);
|
||||||
|
|
||||||
|
if (data->num_y_points) {
|
||||||
|
const int bh = FFMIN(out->height - row * FG_BLOCK_SIZE, FG_BLOCK_SIZE);
|
||||||
|
const ptrdiff_t off = row * FG_BLOCK_SIZE * out->linesize[0];
|
||||||
|
FUNC(fgy_32x32xn_c)((pixel *) ((char *) out->data[0] + off), luma_src,
|
||||||
|
out->linesize[0], params, out->width, scaling[0],
|
||||||
|
grain_lut[0], bh, row HBD_CALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data->num_uv_points[0] && !data->num_uv_points[1] &&
|
||||||
|
!data->chroma_scaling_from_luma)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extend padding pixels
|
||||||
|
if (out->width & ss_x) {
|
||||||
|
pixel *ptr = luma_src;
|
||||||
|
for (int y = 0; y < bh; y++) {
|
||||||
|
ptr[out->width] = ptr[out->width - 1];
|
||||||
|
ptr = (pixel *) ((char *) ptr + (in->linesize[0] << ss_y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->chroma_scaling_from_luma) {
|
||||||
|
for (int pl = 0; pl < 2; pl++)
|
||||||
|
FUNC(fguv_32x32xn_c)((pixel *) ((char *) out->data[1 + pl] + uv_off),
|
||||||
|
(const pixel *) ((const char *) in->data[1 + pl] + uv_off),
|
||||||
|
in->linesize[1], params, cpw, scaling[0],
|
||||||
|
grain_lut[1 + pl], bh, row, luma_src,
|
||||||
|
in->linesize[0], pl, is_id, ss_x, ss_y HBD_CALL);
|
||||||
|
} else {
|
||||||
|
for (int pl = 0; pl < 2; pl++) {
|
||||||
|
if (data->num_uv_points[pl]) {
|
||||||
|
FUNC(fguv_32x32xn_c)((pixel *) ((char *) out->data[1 + pl] + uv_off),
|
||||||
|
(const pixel *) ((const char *) in->data[1 + pl] + uv_off),
|
||||||
|
in->linesize[1], params, cpw, scaling[1 + pl],
|
||||||
|
grain_lut[1 + pl], bh, row, luma_src,
|
||||||
|
in->linesize[0], pl, is_id, ss_x, ss_y HBD_CALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FUNC(apply_film_grain)(AVFrame *out_frame, const AVFrame *in_frame,
|
||||||
|
const AVFilmGrainParams *params HBD_DECL)
|
||||||
|
{
|
||||||
|
entry grain_lut[3][GRAIN_HEIGHT + 1][GRAIN_WIDTH];
|
||||||
|
uint8_t scaling[3][SCALING_SIZE];
|
||||||
|
|
||||||
|
const AVFilmGrainAOMParams *const data = ¶ms->codec.aom;
|
||||||
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(out_frame->format);
|
||||||
|
const int rows = AV_CEIL_RSHIFT(out_frame->height, 5); /* log2(FG_BLOCK_SIZE) */
|
||||||
|
const int subx = desc->log2_chroma_w, suby = desc->log2_chroma_h;
|
||||||
|
|
||||||
|
// Generate grain LUTs as needed
|
||||||
|
FUNC(generate_grain_y_c)(grain_lut[0], params HBD_CALL);
|
||||||
|
if (data->num_uv_points[0] || data->chroma_scaling_from_luma)
|
||||||
|
FUNC(generate_grain_uv_c)(grain_lut[1], grain_lut[0], params, 0, subx, suby HBD_CALL);
|
||||||
|
if (data->num_uv_points[1] || data->chroma_scaling_from_luma)
|
||||||
|
FUNC(generate_grain_uv_c)(grain_lut[2], grain_lut[0], params, 1, subx, suby HBD_CALL);
|
||||||
|
|
||||||
|
// Generate scaling LUTs as needed
|
||||||
|
if (data->num_y_points || data->chroma_scaling_from_luma)
|
||||||
|
FUNC(generate_scaling)(data->y_points, data->num_y_points, scaling[0] HBD_CALL);
|
||||||
|
if (data->num_uv_points[0])
|
||||||
|
FUNC(generate_scaling)(data->uv_points[0], data->num_uv_points[0], scaling[1] HBD_CALL);
|
||||||
|
if (data->num_uv_points[1])
|
||||||
|
FUNC(generate_scaling)(data->uv_points[1], data->num_uv_points[1], scaling[2] HBD_CALL);
|
||||||
|
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
FUNC(apply_grain_row)(out_frame, in_frame, subx, suby, scaling, grain_lut,
|
||||||
|
params, row HBD_CALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -34,6 +34,7 @@
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
#include "hwaccel_internal.h"
|
#include "hwaccel_internal.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "itut35.h"
|
||||||
#include "hwconfig.h"
|
#include "hwconfig.h"
|
||||||
#include "profiles.h"
|
#include "profiles.h"
|
||||||
#include "refstruct.h"
|
#include "refstruct.h"
|
||||||
|
@ -951,7 +952,7 @@ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame,
|
||||||
|
|
||||||
provider_code = bytestream2_get_be16(&gb);
|
provider_code = bytestream2_get_be16(&gb);
|
||||||
switch (provider_code) {
|
switch (provider_code) {
|
||||||
case 0x31: { // atsc_provider_code
|
case ITU_T_T35_PROVIDER_CODE_ATSC: {
|
||||||
uint32_t user_identifier = bytestream2_get_be32(&gb);
|
uint32_t user_identifier = bytestream2_get_be32(&gb);
|
||||||
switch (user_identifier) {
|
switch (user_identifier) {
|
||||||
case MKBETAG('G', 'A', '9', '4'): { // closed captions
|
case MKBETAG('G', 'A', '9', '4'): { // closed captions
|
||||||
|
@ -975,12 +976,12 @@ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x3C: { // smpte_provider_code
|
case ITU_T_T35_PROVIDER_CODE_SMTPE: {
|
||||||
AVDynamicHDRPlus *hdrplus;
|
AVDynamicHDRPlus *hdrplus;
|
||||||
int provider_oriented_code = bytestream2_get_be16(&gb);
|
int provider_oriented_code = bytestream2_get_be16(&gb);
|
||||||
int application_identifier = bytestream2_get_byte(&gb);
|
int application_identifier = bytestream2_get_byte(&gb);
|
||||||
|
|
||||||
if (itut_t35->itu_t_t35_country_code != 0xB5 ||
|
if (itut_t35->itu_t_t35_country_code != ITU_T_T35_COUNTRY_CODE_US ||
|
||||||
provider_oriented_code != 1 || application_identifier != 4)
|
provider_oriented_code != 1 || application_identifier != 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -994,9 +995,10 @@ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame,
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x3B: { // dolby_provider_code
|
case ITU_T_T35_PROVIDER_CODE_DOLBY: {
|
||||||
int provider_oriented_code = bytestream2_get_be32(&gb);
|
int provider_oriented_code = bytestream2_get_be32(&gb);
|
||||||
if (itut_t35->itu_t_t35_country_code != 0xB5 || provider_oriented_code != 0x800)
|
if (itut_t35->itu_t_t35_country_code != ITU_T_T35_COUNTRY_CODE_US ||
|
||||||
|
provider_oriented_code != 0x800)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ret = ff_dovi_rpu_parse(&s->dovi, gb.buffer, gb.buffer_end - gb.buffer);
|
ret = ff_dovi_rpu_parse(&s->dovi, gb.buffer, gb.buffer_end - gb.buffer);
|
||||||
|
@ -1072,9 +1074,11 @@ static int export_film_grain(AVCodecContext *avctx, AVFrame *frame)
|
||||||
{
|
{
|
||||||
AV1DecContext *s = avctx->priv_data;
|
AV1DecContext *s = avctx->priv_data;
|
||||||
const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain;
|
const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain;
|
||||||
|
const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(frame->format);
|
||||||
AVFilmGrainParams *fgp;
|
AVFilmGrainParams *fgp;
|
||||||
AVFilmGrainAOMParams *aom;
|
AVFilmGrainAOMParams *aom;
|
||||||
|
|
||||||
|
av_assert0(pixdesc);
|
||||||
if (!film_grain->apply_grain)
|
if (!film_grain->apply_grain)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1084,6 +1088,14 @@ static int export_film_grain(AVCodecContext *avctx, AVFrame *frame)
|
||||||
|
|
||||||
fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
|
fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
|
||||||
fgp->seed = film_grain->grain_seed;
|
fgp->seed = film_grain->grain_seed;
|
||||||
|
fgp->width = frame->width;
|
||||||
|
fgp->height = frame->height;
|
||||||
|
fgp->color_range = frame->color_range;
|
||||||
|
fgp->color_primaries = frame->color_primaries;
|
||||||
|
fgp->color_trc = frame->color_trc;
|
||||||
|
fgp->color_space = frame->colorspace;
|
||||||
|
fgp->subsampling_x = pixdesc->log2_chroma_w;
|
||||||
|
fgp->subsampling_y = pixdesc->log2_chroma_h;
|
||||||
|
|
||||||
aom = &fgp->codec.aom;
|
aom = &fgp->codec.aom;
|
||||||
aom->chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma;
|
aom->chroma_scaling_from_luma = film_grain->chroma_scaling_from_luma;
|
||||||
|
@ -1138,7 +1150,7 @@ static int set_output_frame(AVCodecContext *avctx, AVFrame *frame)
|
||||||
// TODO: all layers
|
// TODO: all layers
|
||||||
if (s->operating_point_idc &&
|
if (s->operating_point_idc &&
|
||||||
av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id)
|
av_log2(s->operating_point_idc >> 8) > s->cur_frame.spatial_id)
|
||||||
return 0;
|
return AVERROR(EAGAIN);
|
||||||
|
|
||||||
ret = av_frame_ref(frame, srcframe);
|
ret = av_frame_ref(frame, srcframe);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -1333,7 +1345,7 @@ static int av1_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
|
||||||
|
|
||||||
if (s->cur_frame.f->buf[0]) {
|
if (s->cur_frame.f->buf[0]) {
|
||||||
ret = set_output_frame(avctx, frame);
|
ret = set_output_frame(avctx, frame);
|
||||||
if (ret < 0)
|
if (ret < 0 && ret != AVERROR(EAGAIN))
|
||||||
av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n");
|
av_log(avctx, AV_LOG_ERROR, "Set output frame error.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,11 +1457,13 @@ static int av1_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame)
|
||||||
|
|
||||||
if (s->raw_frame_header->show_frame && s->cur_frame.f->buf[0]) {
|
if (s->raw_frame_header->show_frame && s->cur_frame.f->buf[0]) {
|
||||||
ret = set_output_frame(avctx, frame);
|
ret = set_output_frame(avctx, frame);
|
||||||
if (ret < 0) {
|
if (ret < 0 && ret != AVERROR(EAGAIN)) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Set output frame error\n");
|
av_log(avctx, AV_LOG_ERROR, "Set output frame error\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
} else if (show_frame)
|
||||||
|
ret = AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
raw_tile_group = NULL;
|
raw_tile_group = NULL;
|
||||||
s->raw_frame_header = NULL;
|
s->raw_frame_header = NULL;
|
||||||
if (show_frame) {
|
if (show_frame) {
|
||||||
|
|
|
@ -247,8 +247,10 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
|
||||||
&& !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
|
&& !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "%s requires channel layout to be set\n",
|
av_log(avctx, AV_LOG_ERROR, "%s requires channel layout to be set\n",
|
||||||
av_codec_is_decoder(codec) ? "Decoder" : "Encoder");
|
av_codec_is_decoder(codec) ? "Decoder" : "Encoder");
|
||||||
ret = AVERROR(EINVAL);
|
if (!av_codec_is_decoder(codec)) {
|
||||||
goto free_and_end;
|
ret = AVERROR(EINVAL);
|
||||||
|
goto free_and_end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (avctx->ch_layout.nb_channels && !av_channel_layout_check(&avctx->ch_layout)) {
|
if (avctx->ch_layout.nb_channels && !av_channel_layout_check(&avctx->ch_layout)) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Invalid channel layout\n");
|
av_log(avctx, AV_LOG_ERROR, "Invalid channel layout\n");
|
||||||
|
|
|
@ -1665,6 +1665,8 @@ typedef struct AVCodecContext {
|
||||||
#define FF_PROFILE_DTS_ES 30
|
#define FF_PROFILE_DTS_ES 30
|
||||||
#define FF_PROFILE_DTS_96_24 40
|
#define FF_PROFILE_DTS_96_24 40
|
||||||
#define FF_PROFILE_DTS_HD_HRA 50
|
#define FF_PROFILE_DTS_HD_HRA 50
|
||||||
|
#define FF_PROFILE_DTS_HD_HRA_X 51
|
||||||
|
#define FF_PROFILE_DTS_HD_HRA_X_IMAX 52
|
||||||
#define FF_PROFILE_DTS_HD_MA 60
|
#define FF_PROFILE_DTS_HD_MA 60
|
||||||
#define FF_PROFILE_DTS_EXPRESS 70
|
#define FF_PROFILE_DTS_EXPRESS 70
|
||||||
#define FF_PROFILE_DTS_HD_MA_X 61
|
#define FF_PROFILE_DTS_HD_MA_X 61
|
||||||
|
@ -1696,11 +1698,13 @@ typedef struct AVCodecContext {
|
||||||
#define FF_PROFILE_H264_HIGH_422 122
|
#define FF_PROFILE_H264_HIGH_422 122
|
||||||
#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
|
#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
|
||||||
#define FF_PROFILE_H264_STEREO_HIGH 128
|
#define FF_PROFILE_H264_STEREO_HIGH 128
|
||||||
|
#define FF_PROFILE_H264_MULTIVIEW_HIGH_DEPTH 138
|
||||||
#define FF_PROFILE_H264_HIGH_444 144
|
#define FF_PROFILE_H264_HIGH_444 144
|
||||||
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
|
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
|
||||||
#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
|
#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
|
||||||
#define FF_PROFILE_H264_CAVLC_444 44
|
#define FF_PROFILE_H264_CAVLC_444 44
|
||||||
|
|
||||||
|
|
||||||
#define FF_PROFILE_VC1_SIMPLE 0
|
#define FF_PROFILE_VC1_SIMPLE 0
|
||||||
#define FF_PROFILE_VC1_MAIN 1
|
#define FF_PROFILE_VC1_MAIN 1
|
||||||
#define FF_PROFILE_VC1_COMPLEX 2
|
#define FF_PROFILE_VC1_COMPLEX 2
|
||||||
|
@ -2029,6 +2033,13 @@ typedef struct AVCodecContext {
|
||||||
*/
|
*/
|
||||||
int64_t frame_num;
|
int64_t frame_num;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the stream completely progressive?
|
||||||
|
* - decoding: set by avcodec
|
||||||
|
* - encoding: unused
|
||||||
|
*/
|
||||||
|
int progressive_sequence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoding only. May be set by the caller before avcodec_open2() to an
|
* Decoding only. May be set by the caller before avcodec_open2() to an
|
||||||
* av_malloc()'ed array (or via AVOptions). Owned and freed by the decoder
|
* av_malloc()'ed array (or via AVOptions). Owned and freed by the decoder
|
||||||
|
@ -2062,6 +2073,19 @@ typedef struct AVCodecContext {
|
||||||
* Number of entries in side_data_prefer_packet.
|
* Number of entries in side_data_prefer_packet.
|
||||||
*/
|
*/
|
||||||
unsigned nb_side_data_prefer_packet;
|
unsigned nb_side_data_prefer_packet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array containing static side data, such as HDR10 CLL / MDCV structures.
|
||||||
|
* Side data entries should be allocated by usage of helpers defined in
|
||||||
|
* libavutil/frame.h.
|
||||||
|
*
|
||||||
|
* - encoding: may be set by user before calling avcodec_open2() for
|
||||||
|
* encoder configuration. Afterwards owned and freed by the
|
||||||
|
* encoder.
|
||||||
|
* - decoding: unused
|
||||||
|
*/
|
||||||
|
AVFrameSideData **decoded_side_data;
|
||||||
|
int nb_decoded_side_data;
|
||||||
} AVCodecContext;
|
} AVCodecContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2211,6 +2235,12 @@ typedef struct AVSubtitleRect {
|
||||||
char *ass;
|
char *ass;
|
||||||
} AVSubtitleRect;
|
} AVSubtitleRect;
|
||||||
|
|
||||||
|
typedef struct AVSubtitleDVDPalette {
|
||||||
|
uint32_t start_display_time;
|
||||||
|
uint8_t colormap[4];
|
||||||
|
uint8_t alpha[4];
|
||||||
|
} AVSubtitleDVDPalette;
|
||||||
|
|
||||||
typedef struct AVSubtitle {
|
typedef struct AVSubtitle {
|
||||||
uint16_t format; /* 0 = graphics */
|
uint16_t format; /* 0 = graphics */
|
||||||
uint32_t start_display_time; /* relative to packet pts, in ms */
|
uint32_t start_display_time; /* relative to packet pts, in ms */
|
||||||
|
@ -2218,6 +2248,9 @@ typedef struct AVSubtitle {
|
||||||
unsigned num_rects;
|
unsigned num_rects;
|
||||||
AVSubtitleRect **rects;
|
AVSubtitleRect **rects;
|
||||||
int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
|
int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
|
||||||
|
|
||||||
|
unsigned num_dvd_palette;
|
||||||
|
AVSubtitleDVDPalette **dvd_palette;
|
||||||
} AVSubtitle;
|
} AVSubtitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2730,6 +2763,7 @@ typedef struct AVCodecParserContext {
|
||||||
/// Set if the parser has a valid file offset
|
/// Set if the parser has a valid file offset
|
||||||
#define PARSER_FLAG_FETCHED_OFFSET 0x0004
|
#define PARSER_FLAG_FETCHED_OFFSET 0x0004
|
||||||
#define PARSER_FLAG_USE_CODEC_TS 0x1000
|
#define PARSER_FLAG_USE_CODEC_TS 0x1000
|
||||||
|
#define PARSER_FLAG_NO_TIMESTAMP_MANGLING 0x2000
|
||||||
|
|
||||||
int64_t offset; ///< byte offset from starting packet start
|
int64_t offset; ///< byte offset from starting packet start
|
||||||
int64_t cur_frame_end[AV_PARSER_PTS_NB];
|
int64_t cur_frame_end[AV_PARSER_PTS_NB];
|
||||||
|
|
|
@ -166,10 +166,10 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||||
VVC_VPS_NUT, VVC_SPS_NUT, VVC_PPS_NUT,
|
VVC_VPS_NUT, VVC_SPS_NUT, VVC_PPS_NUT,
|
||||||
};
|
};
|
||||||
static const int extradata_nal_types_hevc[] = {
|
static const int extradata_nal_types_hevc[] = {
|
||||||
HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS,
|
HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS, HEVC_NAL_SEI_PREFIX, HEVC_NAL_SEI_SUFFIX,
|
||||||
};
|
};
|
||||||
static const int extradata_nal_types_h264[] = {
|
static const int extradata_nal_types_h264[] = {
|
||||||
H264_NAL_SPS, H264_NAL_PPS,
|
H264_NAL_SPS, H264_NAL_SUB_SPS, H264_NAL_PPS, H264_NAL_SEI,
|
||||||
};
|
};
|
||||||
|
|
||||||
ExtractExtradataContext *s = ctx->priv_data;
|
ExtractExtradataContext *s = ctx->priv_data;
|
||||||
|
@ -206,7 +206,7 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||||
if (nal->type == HEVC_NAL_SPS) has_sps = 1;
|
if (nal->type == HEVC_NAL_SPS) has_sps = 1;
|
||||||
if (nal->type == HEVC_NAL_VPS) has_vps = 1;
|
if (nal->type == HEVC_NAL_VPS) has_vps = 1;
|
||||||
} else {
|
} else {
|
||||||
if (nal->type == H264_NAL_SPS) has_sps = 1;
|
if (nal->type == H264_NAL_SPS || nal->type == H264_NAL_SUB_SPS) has_sps = 1;
|
||||||
}
|
}
|
||||||
} else if (s->remove) {
|
} else if (s->remove) {
|
||||||
filtered_size += nal->raw_size + 3;
|
filtered_size += nal->raw_size + 3;
|
||||||
|
@ -216,7 +216,8 @@ static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
|
||||||
if (extradata_size &&
|
if (extradata_size &&
|
||||||
((ctx->par_in->codec_id == AV_CODEC_ID_VVC && has_sps) ||
|
((ctx->par_in->codec_id == AV_CODEC_ID_VVC && has_sps) ||
|
||||||
(ctx->par_in->codec_id == AV_CODEC_ID_HEVC && has_sps && has_vps) ||
|
(ctx->par_in->codec_id == AV_CODEC_ID_HEVC && has_sps && has_vps) ||
|
||||||
(ctx->par_in->codec_id == AV_CODEC_ID_H264 && has_sps))) {
|
(ctx->par_in->codec_id == AV_CODEC_ID_H264 && has_sps) ||
|
||||||
|
(ctx->par_in->codec_id == AV_CODEC_ID_H264_MVC && has_sps))) {
|
||||||
AVBufferRef *filtered_buf = NULL;
|
AVBufferRef *filtered_buf = NULL;
|
||||||
PutByteContext pb_filtered_data, pb_extradata;
|
PutByteContext pb_filtered_data, pb_extradata;
|
||||||
uint8_t *extradata;
|
uint8_t *extradata;
|
||||||
|
@ -368,6 +369,7 @@ static const struct {
|
||||||
{ AV_CODEC_ID_AVS3, extract_extradata_mpeg4 },
|
{ AV_CODEC_ID_AVS3, extract_extradata_mpeg4 },
|
||||||
{ AV_CODEC_ID_CAVS, extract_extradata_mpeg4 },
|
{ AV_CODEC_ID_CAVS, extract_extradata_mpeg4 },
|
||||||
{ AV_CODEC_ID_H264, extract_extradata_h2645 },
|
{ AV_CODEC_ID_H264, extract_extradata_h2645 },
|
||||||
|
{ AV_CODEC_ID_H264_MVC, extract_extradata_h2645 },
|
||||||
{ AV_CODEC_ID_HEVC, extract_extradata_h2645 },
|
{ AV_CODEC_ID_HEVC, extract_extradata_h2645 },
|
||||||
{ AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg12 },
|
{ AV_CODEC_ID_MPEG1VIDEO, extract_extradata_mpeg12 },
|
||||||
{ AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg12 },
|
{ AV_CODEC_ID_MPEG2VIDEO, extract_extradata_mpeg12 },
|
||||||
|
@ -438,6 +440,7 @@ static const enum AVCodecID codec_ids[] = {
|
||||||
AV_CODEC_ID_AVS3,
|
AV_CODEC_ID_AVS3,
|
||||||
AV_CODEC_ID_CAVS,
|
AV_CODEC_ID_CAVS,
|
||||||
AV_CODEC_ID_H264,
|
AV_CODEC_ID_H264,
|
||||||
|
AV_CODEC_ID_H264_MVC,
|
||||||
AV_CODEC_ID_HEVC,
|
AV_CODEC_ID_HEVC,
|
||||||
AV_CODEC_ID_MPEG1VIDEO,
|
AV_CODEC_ID_MPEG1VIDEO,
|
||||||
AV_CODEC_ID_MPEG2VIDEO,
|
AV_CODEC_ID_MPEG2VIDEO,
|
||||||
|
|
|
@ -76,7 +76,7 @@ static int h264_split(const uint8_t *buf, int buf_size)
|
||||||
if ((state & 0xFFFFFF00) != 0x100)
|
if ((state & 0xFFFFFF00) != 0x100)
|
||||||
break;
|
break;
|
||||||
nalu_type = state & 0x1F;
|
nalu_type = state & 0x1F;
|
||||||
if (nalu_type == H264_NAL_SPS) {
|
if (nalu_type == H264_NAL_SPS || nalu_type == H264_NAL_SUB_SPS) {
|
||||||
has_sps = 1;
|
has_sps = 1;
|
||||||
} else if (nalu_type == H264_NAL_PPS)
|
} else if (nalu_type == H264_NAL_PPS)
|
||||||
has_pps = 1;
|
has_pps = 1;
|
||||||
|
@ -204,6 +204,7 @@ static int remove_extradata(AVBSFContext *ctx, AVPacket *pkt)
|
||||||
i = mpeg4video_split(pkt->data, pkt->size);
|
i = mpeg4video_split(pkt->data, pkt->size);
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_H264:
|
case AV_CODEC_ID_H264:
|
||||||
|
case AV_CODEC_ID_H264_MVC:
|
||||||
i = h264_split(pkt->data, pkt->size);
|
i = h264_split(pkt->data, pkt->size);
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_HEVC:
|
case AV_CODEC_ID_HEVC:
|
||||||
|
|
|
@ -2072,6 +2072,8 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw,
|
||||||
|
|
||||||
tile_x = tile_idx % current->num_tile_columns;
|
tile_x = tile_idx % current->num_tile_columns;
|
||||||
tile_y = tile_idx / current->num_tile_columns;
|
tile_y = tile_idx / current->num_tile_columns;
|
||||||
|
if (tile_y >= current->num_tile_rows)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
ctu_x = 0, ctu_y = 0;
|
ctu_x = 0, ctu_y = 0;
|
||||||
for (j = 0; j < tile_x; j++) {
|
for (j = 0; j < tile_x; j++) {
|
||||||
|
|
|
@ -1959,6 +1959,14 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
||||||
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.id = AV_CODEC_ID_H264_MVC,
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
.name = "h264_mvc",
|
||||||
|
.long_name = NULL_IF_CONFIG_SMALL("H264 MVC"),
|
||||||
|
.props = AV_CODEC_PROP_LOSSY,
|
||||||
|
},
|
||||||
|
|
||||||
/* various PCM "codecs" */
|
/* various PCM "codecs" */
|
||||||
{
|
{
|
||||||
.id = AV_CODEC_ID_PCM_S16LE,
|
.id = AV_CODEC_ID_PCM_S16LE,
|
||||||
|
|
|
@ -323,6 +323,8 @@ enum AVCodecID {
|
||||||
AV_CODEC_ID_VMIX,
|
AV_CODEC_ID_VMIX,
|
||||||
AV_CODEC_ID_LEAD,
|
AV_CODEC_ID_LEAD,
|
||||||
|
|
||||||
|
AV_CODEC_ID_H264_MVC,
|
||||||
|
|
||||||
/* various PCM "codecs" */
|
/* various PCM "codecs" */
|
||||||
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||||
AV_CODEC_ID_PCM_S16LE = 0x10000,
|
AV_CODEC_ID_PCM_S16LE = 0x10000,
|
||||||
|
|
|
@ -2369,9 +2369,14 @@ int ff_dca_core_filter_frame(DCACoreDecoder *s, AVFrame *frame)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// Set profile, bit rate, etc
|
// Set profile, bit rate, etc
|
||||||
if (s->ext_audio_mask & DCA_EXSS_MASK)
|
if (s->ext_audio_mask & DCA_EXSS_MASK) {
|
||||||
avctx->profile = AV_PROFILE_DTS_HD_HRA;
|
if (dca->exss.x_syncword_present)
|
||||||
else if (s->ext_audio_mask & (DCA_CSS_XXCH | DCA_CSS_XCH))
|
avctx->profile = FF_PROFILE_DTS_HD_HRA_X;
|
||||||
|
else if (dca->exss.x_imax_syncword_present)
|
||||||
|
avctx->profile = FF_PROFILE_DTS_HD_HRA_X_IMAX;
|
||||||
|
else
|
||||||
|
avctx->profile = AV_PROFILE_DTS_HD_HRA;
|
||||||
|
} else if (s->ext_audio_mask & (DCA_CSS_XXCH | DCA_CSS_XCH))
|
||||||
avctx->profile = AV_PROFILE_DTS_ES;
|
avctx->profile = AV_PROFILE_DTS_ES;
|
||||||
else if (s->ext_audio_mask & DCA_CSS_X96)
|
else if (s->ext_audio_mask & DCA_CSS_X96)
|
||||||
avctx->profile = AV_PROFILE_DTS_96_24;
|
avctx->profile = AV_PROFILE_DTS_96_24;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dcadec.h"
|
#include "dcadec.h"
|
||||||
|
#include "dca_syncwords.h"
|
||||||
|
|
||||||
static void parse_xll_parameters(DCAExssParser *s, DCAExssAsset *asset)
|
static void parse_xll_parameters(DCAExssParser *s, DCAExssAsset *asset)
|
||||||
{
|
{
|
||||||
|
@ -510,5 +511,17 @@ int ff_dca_exss_parse(DCAExssParser *s, const uint8_t *data, int size)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for extradata extensions
|
||||||
|
if ((s->exss_size - offset) > 10) {
|
||||||
|
if (AV_RB32(data + offset) == 0x3a429b0a) {
|
||||||
|
unsigned int extradata_syncword = AV_RB32(data + offset + 6);
|
||||||
|
if (extradata_syncword == DCA_SYNCWORD_XLL_X) {
|
||||||
|
s->x_syncword_present = 1;
|
||||||
|
} else if ((extradata_syncword >> 1) == (DCA_SYNCWORD_XLL_X_IMAX >> 1)) {
|
||||||
|
s->x_imax_syncword_present = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,9 @@ typedef struct DCAExssParser {
|
||||||
int nmixoutconfigs; ///< Number of mixing configurations
|
int nmixoutconfigs; ///< Number of mixing configurations
|
||||||
int nmixoutchs[4]; ///< Speaker layout mask for mixer output channels
|
int nmixoutchs[4]; ///< Speaker layout mask for mixer output channels
|
||||||
|
|
||||||
|
int x_syncword_present; ///< DTS:X extension syncword detected
|
||||||
|
int x_imax_syncword_present;///< DTS:X IMAX extension syncword detected
|
||||||
|
|
||||||
DCAExssAsset assets[1]; ///< Audio asset descriptors
|
DCAExssAsset assets[1]; ///< Audio asset descriptors
|
||||||
} DCAExssParser;
|
} DCAExssParser;
|
||||||
|
|
||||||
|
|
|
@ -1326,8 +1326,8 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
|
||||||
goto try_again;
|
goto try_again;
|
||||||
}
|
}
|
||||||
if (hw_config->hwaccel) {
|
if (hw_config->hwaccel) {
|
||||||
av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel "
|
av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel %s "
|
||||||
"initialisation.\n", desc->name);
|
"initialisation.\n", desc->name, hw_config->hwaccel->p.name);
|
||||||
err = hwaccel_init(avctx, hw_config->hwaccel);
|
err = hwaccel_init(avctx, hw_config->hwaccel);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto try_again;
|
goto try_again;
|
||||||
|
|
|
@ -87,6 +87,8 @@
|
||||||
#define AV_PROFILE_DTS_ES 30
|
#define AV_PROFILE_DTS_ES 30
|
||||||
#define AV_PROFILE_DTS_96_24 40
|
#define AV_PROFILE_DTS_96_24 40
|
||||||
#define AV_PROFILE_DTS_HD_HRA 50
|
#define AV_PROFILE_DTS_HD_HRA 50
|
||||||
|
#define AV_PROFILE_DTS_HD_HRA_X 51
|
||||||
|
#define AV_PROFILE_DTS_HD_HRA_X_IMAX 52
|
||||||
#define AV_PROFILE_DTS_HD_MA 60
|
#define AV_PROFILE_DTS_HD_MA 60
|
||||||
#define AV_PROFILE_DTS_EXPRESS 70
|
#define AV_PROFILE_DTS_EXPRESS 70
|
||||||
#define AV_PROFILE_DTS_HD_MA_X 61
|
#define AV_PROFILE_DTS_HD_MA_X 61
|
||||||
|
|
|
@ -68,7 +68,7 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0)
|
||||||
s->mapping = s0->mapping;
|
s->mapping = s0->mapping;
|
||||||
s->color = s0->color;
|
s->color = s0->color;
|
||||||
s->dv_profile = s0->dv_profile;
|
s->dv_profile = s0->dv_profile;
|
||||||
for (int i = 0; i < DOVI_MAX_DM_ID; i++)
|
for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
|
||||||
ff_refstruct_replace(&s->vdr[i], s0->vdr[i]);
|
ff_refstruct_replace(&s->vdr[i], s0->vdr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ static inline uint64_t get_ue_coef(GetBitContext *gb, const AVDOVIRpuDataHeader
|
||||||
case RPU_COEFF_FIXED:
|
case RPU_COEFF_FIXED:
|
||||||
ipart = get_ue_golomb_long(gb);
|
ipart = get_ue_golomb_long(gb);
|
||||||
fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
|
fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
|
||||||
return (ipart << hdr->coef_log2_denom) + fpart.u32;
|
return (ipart << hdr->coef_log2_denom) | fpart.u32;
|
||||||
|
|
||||||
case RPU_COEFF_FLOAT:
|
case RPU_COEFF_FLOAT:
|
||||||
fpart.u32 = get_bits_long(gb, 32);
|
fpart.u32 = get_bits_long(gb, 32);
|
||||||
|
@ -164,7 +164,7 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *
|
||||||
case RPU_COEFF_FIXED:
|
case RPU_COEFF_FIXED:
|
||||||
ipart = get_se_golomb_long(gb);
|
ipart = get_se_golomb_long(gb);
|
||||||
fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
|
fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
|
||||||
return ipart * (1LL << hdr->coef_log2_denom) + fpart.u32;
|
return ipart * (1LL << hdr->coef_log2_denom) | fpart.u32;
|
||||||
|
|
||||||
case RPU_COEFF_FLOAT:
|
case RPU_COEFF_FLOAT:
|
||||||
fpart.u32 = get_bits_long(gb, 32);
|
fpart.u32 = get_bits_long(gb, 32);
|
||||||
|
|
|
@ -146,16 +146,12 @@ static void guess_palette(DVDSubContext* ctx,
|
||||||
uint32_t *rgba_palette,
|
uint32_t *rgba_palette,
|
||||||
uint32_t subtitle_color)
|
uint32_t subtitle_color)
|
||||||
{
|
{
|
||||||
static const uint8_t level_map[4][4] = {
|
static const uint8_t level_map[4] = {
|
||||||
// this configuration (full range, lowest to highest) in tests
|
// this configuration (full range, lowest to highest) in tests
|
||||||
// seemed most common, so assume this
|
// seemed most common, so assume this
|
||||||
{0xff},
|
0x00, 0xe0, 0x80, 0x20
|
||||||
{0x00, 0xff},
|
|
||||||
{0x00, 0x80, 0xff},
|
|
||||||
{0x00, 0x55, 0xaa, 0xff},
|
|
||||||
};
|
};
|
||||||
uint8_t color_used[16] = { 0 };
|
int i, level, r, g, b;
|
||||||
int nb_opaque_colors, i, level, j, r, g, b;
|
|
||||||
uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
|
uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
|
||||||
|
|
||||||
if(ctx->has_palette) {
|
if(ctx->has_palette) {
|
||||||
|
@ -168,33 +164,13 @@ static void guess_palette(DVDSubContext* ctx,
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
rgba_palette[i] = 0;
|
rgba_palette[i] = 0;
|
||||||
|
|
||||||
nb_opaque_colors = 0;
|
|
||||||
for(i = 0; i < 4; i++) {
|
|
||||||
if (alpha[i] != 0 && !color_used[colormap[i]]) {
|
|
||||||
color_used[colormap[i]] = 1;
|
|
||||||
nb_opaque_colors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nb_opaque_colors == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
memset(color_used, 0, 16);
|
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
if (alpha[i] != 0) {
|
if (alpha[i] != 0) {
|
||||||
if (!color_used[colormap[i]]) {
|
level = level_map[i];
|
||||||
level = level_map[nb_opaque_colors - 1][j];
|
r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
|
||||||
r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
|
g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
|
||||||
g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
|
b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
|
||||||
b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
|
rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17U) << 24);
|
||||||
rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17U) << 24);
|
|
||||||
color_used[colormap[i]] = (i + 1);
|
|
||||||
j++;
|
|
||||||
} else {
|
|
||||||
rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
|
|
||||||
((alpha[i] * 17U) << 24);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,7 +324,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
|
||||||
case 0xff:
|
case 0xff:
|
||||||
goto the_end;
|
goto the_end;
|
||||||
default:
|
default:
|
||||||
ff_dlog(NULL, "unrecognised subpicture command 0x%x\n", cmd);
|
av_log(ctx, AV_LOG_WARNING, "unrecognised subpicture command 0x%x\n", cmd);
|
||||||
goto the_end;
|
goto the_end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,6 +332,14 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
|
||||||
if (offset1 >= buf_size || offset2 >= buf_size)
|
if (offset1 >= buf_size || offset2 >= buf_size)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
/* store dvd palette info in subtitle struct for use by caller */
|
||||||
|
i = sub_header->num_dvd_palette++;
|
||||||
|
sub_header->dvd_palette = av_realloc(sub_header->dvd_palette, sizeof(AVSubtitleDVDPalette *) * (i+1));
|
||||||
|
sub_header->dvd_palette[i] = av_mallocz(sizeof(AVSubtitleDVDPalette));
|
||||||
|
sub_header->dvd_palette[i]->start_display_time = (date << 10) / 90;
|
||||||
|
memcpy(sub_header->dvd_palette[i]->colormap, colormap, 4);
|
||||||
|
memcpy(sub_header->dvd_palette[i]->alpha, alpha, 4);
|
||||||
|
/* parse rle subtitles */
|
||||||
if (offset1 >= 0 && offset2 >= 0) {
|
if (offset1 >= 0 && offset2 >= 0) {
|
||||||
int w, h;
|
int w, h;
|
||||||
uint8_t *bitmap;
|
uint8_t *bitmap;
|
||||||
|
|
|
@ -754,14 +754,13 @@ static void *get_surface(const AVCodecContext *avctx, const AVFrame *frame)
|
||||||
{
|
{
|
||||||
#if CONFIG_D3D11VA
|
#if CONFIG_D3D11VA
|
||||||
if (frame->format == AV_PIX_FMT_D3D11) {
|
if (frame->format == AV_PIX_FMT_D3D11) {
|
||||||
FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
|
AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
|
||||||
intptr_t index = (intptr_t)frame->data[1];
|
intptr_t index = (intptr_t)frame->data[1];
|
||||||
if (index < 0 || index >= sctx->nb_d3d11_views ||
|
if (index < 0 || index >= D3D11VA_CONTEXT(ctx)->surface_count) {
|
||||||
sctx->d3d11_texture != (ID3D11Texture2D *)frame->data[0]) {
|
|
||||||
av_log((void *)avctx, AV_LOG_ERROR, "get_buffer frame is invalid!\n");
|
av_log((void *)avctx, AV_LOG_ERROR, "get_buffer frame is invalid!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return sctx->d3d11_views[index];
|
return D3D11VA_CONTEXT(ctx)->surface[index];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return frame->data[3];
|
return frame->data[3];
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
#include "av1dec.h"
|
#include "av1dec.h"
|
||||||
#include "hwaccel_internal.h"
|
#include "hwaccel_internal.h"
|
||||||
|
|
||||||
|
#if !HAVE_DXVA_PICPARAMS_AV1
|
||||||
|
#include "compat/windows/dxva_av1.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_TILES 256
|
#define MAX_TILES 256
|
||||||
|
|
||||||
struct AV1DXVAContext {
|
struct AV1DXVAContext {
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
#include "hevcdec.h"
|
#include "hevcdec.h"
|
||||||
#include "hwaccel_internal.h"
|
#include "hwaccel_internal.h"
|
||||||
|
|
||||||
|
#if !HAVE_DXVA_PICPARAMS_HEVC
|
||||||
|
#include "compat/windows/dxva_hevc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_SLICES 256
|
#define MAX_SLICES 256
|
||||||
|
|
||||||
struct hevc_dxva2_picture_context {
|
struct hevc_dxva2_picture_context {
|
||||||
|
@ -164,7 +168,7 @@ void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVACo
|
||||||
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
|
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
|
||||||
const HEVCFrame *frame = NULL;
|
const HEVCFrame *frame = NULL;
|
||||||
while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
|
while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
|
||||||
if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
|
if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)) && !h->DPB[j].missing)
|
||||||
frame = &h->DPB[j];
|
frame = &h->DPB[j];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct dxva2_picture_context {
|
||||||
|
|
||||||
const uint8_t *bitstream;
|
const uint8_t *bitstream;
|
||||||
unsigned bitstream_size;
|
unsigned bitstream_size;
|
||||||
|
int frame_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ff_dxva2_mpeg2_fill_picture_parameters(AVCodecContext *avctx,
|
void ff_dxva2_mpeg2_fill_picture_parameters(AVCodecContext *avctx,
|
||||||
|
@ -272,6 +273,7 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
|
||||||
ctx_pic->slice_count = 0;
|
ctx_pic->slice_count = 0;
|
||||||
ctx_pic->bitstream_size = 0;
|
ctx_pic->bitstream_size = 0;
|
||||||
ctx_pic->bitstream = NULL;
|
ctx_pic->bitstream = NULL;
|
||||||
|
ctx_pic->frame_start = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,8 +307,9 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
|
||||||
s->current_picture_ptr->hwaccel_picture_private;
|
s->current_picture_ptr->hwaccel_picture_private;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
|
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0 || !ctx_pic->frame_start)
|
||||||
return -1;
|
return -1;
|
||||||
|
ctx_pic->frame_start = 0;
|
||||||
ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr->f,
|
ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr->f,
|
||||||
&ctx_pic->pp, sizeof(ctx_pic->pp),
|
&ctx_pic->pp, sizeof(ctx_pic->pp),
|
||||||
&ctx_pic->qm, sizeof(ctx_pic->qm),
|
&ctx_pic->qm, sizeof(ctx_pic->qm),
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
#include "hwaccel_internal.h"
|
#include "hwaccel_internal.h"
|
||||||
#include "vp9shared.h"
|
#include "vp9shared.h"
|
||||||
|
|
||||||
|
#if !HAVE_DXVA_PICPARAMS_VP9
|
||||||
|
#include "compat/windows/dxva_vpx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct vp9_dxva2_picture_context {
|
struct vp9_dxva2_picture_context {
|
||||||
DXVA_PicParams_VP9 pp;
|
DXVA_PicParams_VP9 pp;
|
||||||
DXVA_Slice_VPx_Short slice;
|
DXVA_Slice_VPx_Short slice;
|
||||||
|
|
|
@ -236,17 +236,9 @@ done:
|
||||||
av_free(name);
|
av_free(name);
|
||||||
av_free(message);
|
av_free(message);
|
||||||
|
|
||||||
if (class_class) {
|
(*env)->DeleteLocalRef(env, class_class);
|
||||||
(*env)->DeleteLocalRef(env, class_class);
|
(*env)->DeleteLocalRef(env, exception_class);
|
||||||
}
|
(*env)->DeleteLocalRef(env, string);
|
||||||
|
|
||||||
if (exception_class) {
|
|
||||||
(*env)->DeleteLocalRef(env, exception_class);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string) {
|
|
||||||
(*env)->DeleteLocalRef(env, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define AVCODEC_FFJNI_H
|
#define AVCODEC_FFJNI_H
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attach permanently a JNI environment to the current thread and retrieve it.
|
* Attach permanently a JNI environment to the current thread and retrieve it.
|
||||||
|
@ -105,7 +106,7 @@ struct FFJniField {
|
||||||
const char *method;
|
const char *method;
|
||||||
const char *signature;
|
const char *signature;
|
||||||
enum FFJniFieldType type;
|
enum FFJniFieldType type;
|
||||||
int offset;
|
size_t offset;
|
||||||
int mandatory;
|
int mandatory;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "bswapdsp.h"
|
#include "bswapdsp.h"
|
||||||
#include "codec_internal.h"
|
#include "codec_internal.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "threadframe.h"
|
||||||
|
|
||||||
#define FPS_TAG MKTAG('F', 'P', 'S', 'x')
|
#define FPS_TAG MKTAG('F', 'P', 'S', 'x')
|
||||||
#define VLC_BITS 11
|
#define VLC_BITS 11
|
||||||
|
@ -52,10 +53,15 @@
|
||||||
typedef struct FrapsContext {
|
typedef struct FrapsContext {
|
||||||
AVCodecContext *avctx;
|
AVCodecContext *avctx;
|
||||||
BswapDSPContext bdsp;
|
BswapDSPContext bdsp;
|
||||||
|
int cur_index, prev_index;
|
||||||
|
int next_cur_index, next_prev_index;
|
||||||
|
ThreadFrame frames[2];
|
||||||
uint8_t *tmpbuf;
|
uint8_t *tmpbuf;
|
||||||
int tmpbuf_size;
|
int tmpbuf_size;
|
||||||
} FrapsContext;
|
} FrapsContext;
|
||||||
|
|
||||||
|
static av_cold int decode_end(AVCodecContext *avctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initializes decoder
|
* initializes decoder
|
||||||
* @param avctx codec context
|
* @param avctx codec context
|
||||||
|
@ -64,12 +70,46 @@ typedef struct FrapsContext {
|
||||||
static av_cold int decode_init(AVCodecContext *avctx)
|
static av_cold int decode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
FrapsContext * const s = avctx->priv_data;
|
FrapsContext * const s = avctx->priv_data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
s->prev_index = 0;
|
||||||
|
s->cur_index = 1;
|
||||||
|
|
||||||
s->avctx = avctx;
|
s->avctx = avctx;
|
||||||
s->tmpbuf = NULL;
|
s->tmpbuf = NULL;
|
||||||
|
|
||||||
ff_bswapdsp_init(&s->bdsp);
|
ff_bswapdsp_init(&s->bdsp);
|
||||||
|
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
|
||||||
|
s->frames[i].f = av_frame_alloc();
|
||||||
|
if (!s->frames[i].f) {
|
||||||
|
decode_end(avctx);
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
|
||||||
|
{
|
||||||
|
FrapsContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
if (avctx == avctx_from) return 0;
|
||||||
|
|
||||||
|
dst->cur_index = src->next_cur_index;
|
||||||
|
dst->prev_index = src->next_prev_index;
|
||||||
|
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
|
||||||
|
ff_thread_release_ext_buffer(&dst->frames[i]);
|
||||||
|
if (src->frames[i].f->data[0]) {
|
||||||
|
ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,18 +172,52 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
static void frame_copy(FrapsContext *s,
|
||||||
|
uint8_t *dst_data[3], const int dst_linesizes[3],
|
||||||
|
uint8_t *src_data[3], const int src_linesizes[3],
|
||||||
|
unsigned int version, int width, int height)
|
||||||
|
{
|
||||||
|
int i, k, h, bwidth;
|
||||||
|
uint8_t *src, *dst;
|
||||||
|
int planes = (version & 1) ? 1 : 3;
|
||||||
|
|
||||||
|
for (i = 0; i < planes; i++) {
|
||||||
|
dst = dst_data[i];
|
||||||
|
src = src_data[i];
|
||||||
|
if (version & 1) {
|
||||||
|
/* RGB data */
|
||||||
|
h = height;
|
||||||
|
bwidth = width * 3;
|
||||||
|
} else {
|
||||||
|
/* YUV 4:2:0 data */
|
||||||
|
h = i ? height >> 1 : height;
|
||||||
|
bwidth = i ? width >> 1 : width;
|
||||||
|
}
|
||||||
|
|
||||||
|
ff_thread_await_progress(&s->frames[s->prev_index], i, 0);
|
||||||
|
for (k = 0; k < h; k++) {
|
||||||
|
memcpy(dst, src, bwidth);
|
||||||
|
dst += dst_linesizes[i];
|
||||||
|
src += src_linesizes[i];
|
||||||
|
}
|
||||||
|
ff_thread_report_progress(&s->frames[s->cur_index], i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int decode_frame(AVCodecContext *avctx, AVFrame *fout,
|
||||||
int *got_frame, AVPacket *avpkt)
|
int *got_frame, AVPacket *avpkt)
|
||||||
{
|
{
|
||||||
FrapsContext * const s = avctx->priv_data;
|
FrapsContext * const s = avctx->priv_data;
|
||||||
const uint8_t *buf = avpkt->data;
|
const uint8_t *buf = avpkt->data;
|
||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
|
ThreadFrame *frame, *prev_frame;
|
||||||
|
AVFrame *f;
|
||||||
uint32_t header;
|
uint32_t header;
|
||||||
unsigned int version,header_size;
|
unsigned int version,header_size;
|
||||||
const uint32_t *buf32;
|
const uint32_t *buf32;
|
||||||
uint32_t *luma1,*luma2,*cb,*cr;
|
uint32_t *luma1,*luma2,*cb,*cr;
|
||||||
uint32_t offs[4];
|
uint32_t offs[4];
|
||||||
int i, j, ret, is_chroma;
|
int i, j, ret, is_chroma, is_Pframe;
|
||||||
const int planes = 3;
|
const int planes = 3;
|
||||||
int is_pal;
|
int is_pal;
|
||||||
uint8_t *out;
|
uint8_t *out;
|
||||||
|
@ -153,6 +227,10 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frame = &s->frames[s->cur_index];
|
||||||
|
prev_frame = &s->frames[s->prev_index];
|
||||||
|
f = frame->f;
|
||||||
|
|
||||||
header = AV_RL32(buf);
|
header = AV_RL32(buf);
|
||||||
version = header & 0xff;
|
version = header & 0xff;
|
||||||
is_pal = buf[1] == 2 && version == 1;
|
is_pal = buf[1] == 2 && version == 1;
|
||||||
|
@ -179,22 +257,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
if (version == 0) needed_size /= 2;
|
if (version == 0) needed_size /= 2;
|
||||||
needed_size += header_size;
|
needed_size += header_size;
|
||||||
/* bit 31 means same as previous pic */
|
/* bit 31 means same as previous pic */
|
||||||
if (header & (1U<<31)) {
|
is_Pframe = (header & (1U<<31)) ? 1 : 0;
|
||||||
*got_frame = 0;
|
if (!is_Pframe && buf_size != needed_size) {
|
||||||
return buf_size;
|
|
||||||
}
|
|
||||||
if (buf_size != needed_size) {
|
|
||||||
av_log(avctx, AV_LOG_ERROR,
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
"Invalid frame length %d (should be %d)\n",
|
"Invalid frame length %d (should be %d)\n",
|
||||||
buf_size, needed_size);
|
buf_size, needed_size);
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* skip frame */
|
is_Pframe = buf_size == 8 ? 1 : 0;
|
||||||
if (buf_size == 8) {
|
if (!is_Pframe) {
|
||||||
*got_frame = 0;
|
|
||||||
return buf_size;
|
|
||||||
}
|
|
||||||
if (AV_RL32(buf) != FPS_TAG || buf_size < planes*1024 + 24) {
|
if (AV_RL32(buf) != FPS_TAG || buf_size < planes*1024 + 24) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "error in data stream\n");
|
av_log(avctx, AV_LOG_ERROR, "error in data stream\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
@ -212,19 +284,43 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
if (!s->tmpbuf)
|
if (!s->tmpbuf)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f->pict_type = AV_PICTURE_TYPE_I;
|
if (is_Pframe && !prev_frame->f->data[0]) {
|
||||||
f->flags |= AV_FRAME_FLAG_KEY;
|
av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
ff_thread_release_ext_buffer(frame);
|
||||||
|
|
||||||
|
f->pict_type = is_Pframe ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
|
||||||
|
f->flags |= is_Pframe ? 0 : AV_FRAME_FLAG_KEY;;
|
||||||
|
|
||||||
avctx->pix_fmt = version & 1 ? is_pal ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
|
avctx->pix_fmt = version & 1 ? is_pal ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
|
||||||
avctx->color_range = version & 1 ? AVCOL_RANGE_UNSPECIFIED
|
avctx->color_range = version & 1 ? AVCOL_RANGE_UNSPECIFIED
|
||||||
: AVCOL_RANGE_JPEG;
|
: AVCOL_RANGE_JPEG;
|
||||||
avctx->colorspace = version & 1 ? AVCOL_SPC_UNSPECIFIED : AVCOL_SPC_BT709;
|
avctx->colorspace = version & 1 ? AVCOL_SPC_UNSPECIFIED : AVCOL_SPC_BT709;
|
||||||
|
|
||||||
if ((ret = ff_thread_get_buffer(avctx, f, 0)) < 0)
|
if ((ret = ff_thread_get_ext_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
s->next_prev_index = s->cur_index;
|
||||||
|
s->next_cur_index = (s->cur_index - 1) & 1;
|
||||||
|
|
||||||
|
ff_thread_finish_setup(avctx);
|
||||||
|
|
||||||
|
/* Copy previous frame */
|
||||||
|
if (is_Pframe) {
|
||||||
|
frame_copy(s,
|
||||||
|
frame->f->data,
|
||||||
|
frame->f->linesize,
|
||||||
|
prev_frame->f->data,
|
||||||
|
prev_frame->f->linesize,
|
||||||
|
version, avctx->width, avctx->height);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
|
@ -250,6 +346,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
*cb++ = *buf32++;
|
*cb++ = *buf32++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ff_thread_report_progress(frame, INT_MAX, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -272,6 +369,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
&buf[y * avctx->width * 3],
|
&buf[y * avctx->width * 3],
|
||||||
3 * avctx->width);
|
3 * avctx->width);
|
||||||
}
|
}
|
||||||
|
ff_thread_report_progress(frame, INT_MAX, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -288,8 +386,13 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
buf + offs[i], offs[i + 1] - offs[i],
|
buf + offs[i], offs[i + 1] - offs[i],
|
||||||
is_chroma, 1)) < 0) {
|
is_chroma, 1)) < 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
|
av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
|
||||||
return ret;
|
if (avctx->active_thread_type & FF_THREAD_FRAME) {
|
||||||
}
|
ff_thread_report_progress(frame, INT_MAX, 0);
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
return ret;
|
||||||
|
} else
|
||||||
|
ff_thread_report_progress(frame, i, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -300,7 +403,10 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
-f->linesize[0], avctx->width, avctx->height,
|
-f->linesize[0], avctx->width, avctx->height,
|
||||||
buf + offs[i], offs[i + 1] - offs[i], 0, 3)) < 0) {
|
buf + offs[i], offs[i + 1] - offs[i], 0, 3)) < 0) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
|
av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
|
||||||
return ret;
|
if (avctx->active_thread_type & FF_THREAD_FRAME)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out = f->data[0];
|
out = f->data[0];
|
||||||
|
@ -314,11 +420,21 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
}
|
}
|
||||||
out += f->linesize[0] - 3*avctx->width;
|
out += f->linesize[0] - 3*avctx->width;
|
||||||
}
|
}
|
||||||
|
ff_thread_report_progress(frame, INT_MAX, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if ((ret = av_frame_ref(fout, frame->f)) < 0)
|
||||||
|
return ret;
|
||||||
*got_frame = 1;
|
*got_frame = 1;
|
||||||
|
|
||||||
|
s->prev_index = s->next_prev_index;
|
||||||
|
s->cur_index = s->next_cur_index;
|
||||||
|
|
||||||
|
/* Only release frames that aren't used anymore */
|
||||||
|
ff_thread_release_ext_buffer(&s->frames[s->cur_index]);
|
||||||
|
|
||||||
return buf_size;
|
return buf_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,8 +446,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *f,
|
||||||
static av_cold int decode_end(AVCodecContext *avctx)
|
static av_cold int decode_end(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
FrapsContext *s = avctx->priv_data;
|
FrapsContext *s = avctx->priv_data;
|
||||||
|
int i;
|
||||||
|
|
||||||
av_freep(&s->tmpbuf);
|
av_freep(&s->tmpbuf);
|
||||||
|
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
|
||||||
|
if (s->frames[i].f)
|
||||||
|
ff_thread_release_ext_buffer(&s->frames[i]);
|
||||||
|
av_frame_free(&s->frames[i].f);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,4 +469,6 @@ const FFCodec ff_fraps_decoder = {
|
||||||
.close = decode_end,
|
.close = decode_end,
|
||||||
FF_CODEC_DECODE_CB(decode_frame),
|
FF_CODEC_DECODE_CB(decode_frame),
|
||||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
|
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
|
||||||
|
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
|
||||||
|
UPDATE_THREAD_CONTEXT(update_thread_context),
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "get_bits.h"
|
#include "get_bits.h"
|
||||||
#include "golomb.h"
|
#include "golomb.h"
|
||||||
#include "h2645_sei.h"
|
#include "h2645_sei.h"
|
||||||
|
#include "itut35.h"
|
||||||
|
|
||||||
#define IS_H264(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_H264 : CONFIG_H264_SEI)
|
#define IS_H264(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_H264 : CONFIG_H264_SEI)
|
||||||
#define IS_HEVC(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_HEVC : CONFIG_HEVC_SEI)
|
#define IS_HEVC(codec_id) (CONFIG_H264_SEI && CONFIG_HEVC_SEI ? codec_id == AV_CODEC_ID_HEVC : CONFIG_HEVC_SEI)
|
||||||
|
@ -140,7 +141,8 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb,
|
||||||
bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte
|
bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte
|
||||||
}
|
}
|
||||||
|
|
||||||
if (country_code != 0xB5 && country_code != 0x26) { // usa_country_code and cn_country_code
|
if (country_code != ITU_T_T35_COUNTRY_CODE_US &&
|
||||||
|
country_code != ITU_T_T35_COUNTRY_CODE_CN) {
|
||||||
av_log(logctx, AV_LOG_VERBOSE,
|
av_log(logctx, AV_LOG_VERBOSE,
|
||||||
"Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
|
"Unsupported User Data Registered ITU-T T35 SEI message (country_code = %d)\n",
|
||||||
country_code);
|
country_code);
|
||||||
|
@ -151,7 +153,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb,
|
||||||
provider_code = bytestream2_get_be16u(gb);
|
provider_code = bytestream2_get_be16u(gb);
|
||||||
|
|
||||||
switch (provider_code) {
|
switch (provider_code) {
|
||||||
case 0x31: { // atsc_provider_code
|
case ITU_T_T35_PROVIDER_CODE_ATSC: {
|
||||||
uint32_t user_identifier;
|
uint32_t user_identifier;
|
||||||
|
|
||||||
if (bytestream2_get_bytes_left(gb) < 4)
|
if (bytestream2_get_bytes_left(gb) < 4)
|
||||||
|
@ -172,7 +174,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if CONFIG_HEVC_SEI
|
#if CONFIG_HEVC_SEI
|
||||||
case 0x04: { // cuva_provider_code
|
case ITU_T_T35_PROVIDER_CODE_CUVA: {
|
||||||
const uint16_t cuva_provider_oriented_code = 0x0005;
|
const uint16_t cuva_provider_oriented_code = 0x0005;
|
||||||
uint16_t provider_oriented_code;
|
uint16_t provider_oriented_code;
|
||||||
|
|
||||||
|
@ -188,7 +190,7 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x3C: { // smpte_provider_code
|
case ITU_T_T35_PROVIDER_CODE_SMTPE: {
|
||||||
// A/341 Amendment - 2094-40
|
// A/341 Amendment - 2094-40
|
||||||
const uint16_t smpte2094_40_provider_oriented_code = 0x0001;
|
const uint16_t smpte2094_40_provider_oriented_code = 0x0001;
|
||||||
const uint8_t smpte2094_40_application_identifier = 0x04;
|
const uint8_t smpte2094_40_application_identifier = 0x04;
|
||||||
|
@ -209,6 +211,24 @@ static int decode_registered_user_data(H2645SEI *h, GetByteContext *gb,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x5890: { // aom_provider_code
|
||||||
|
const uint16_t aom_grain_provider_oriented_code = 0x0001;
|
||||||
|
uint16_t provider_oriented_code;
|
||||||
|
|
||||||
|
if (!IS_HEVC(codec_id))
|
||||||
|
goto unsupported_provider_code;
|
||||||
|
|
||||||
|
if (bytestream2_get_bytes_left(gb) < 2)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
|
provider_oriented_code = bytestream2_get_byteu(gb);
|
||||||
|
if (provider_oriented_code == aom_grain_provider_oriented_code) {
|
||||||
|
return ff_aom_parse_film_grain_sets(&h->aom_film_grain,
|
||||||
|
gb->buffer,
|
||||||
|
bytestream2_get_bytes_left(gb));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
unsupported_provider_code:
|
unsupported_provider_code:
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -641,35 +661,45 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
|
||||||
h274 = &fgp->codec.h274;
|
h274 = &fgp->codec.h274;
|
||||||
|
|
||||||
fgp->seed = seed;
|
fgp->seed = seed;
|
||||||
|
fgp->width = frame->width;
|
||||||
|
fgp->height = frame->height;
|
||||||
|
|
||||||
|
/* H.274 mandates film grain be applied to 4:4:4 frames */
|
||||||
|
fgp->subsampling_x = fgp->subsampling_y = 0;
|
||||||
|
|
||||||
h274->model_id = fgc->model_id;
|
h274->model_id = fgc->model_id;
|
||||||
if (fgc->separate_colour_description_present_flag) {
|
if (fgc->separate_colour_description_present_flag) {
|
||||||
h274->bit_depth_luma = fgc->bit_depth_luma;
|
fgp->bit_depth_luma = fgc->bit_depth_luma;
|
||||||
h274->bit_depth_chroma = fgc->bit_depth_chroma;
|
fgp->bit_depth_chroma = fgc->bit_depth_chroma;
|
||||||
h274->color_range = fgc->full_range + 1;
|
fgp->color_range = fgc->full_range + 1;
|
||||||
h274->color_primaries = fgc->color_primaries;
|
fgp->color_primaries = fgc->color_primaries;
|
||||||
h274->color_trc = fgc->transfer_characteristics;
|
fgp->color_trc = fgc->transfer_characteristics;
|
||||||
h274->color_space = fgc->matrix_coeffs;
|
fgp->color_space = fgc->matrix_coeffs;
|
||||||
} else {
|
} else {
|
||||||
h274->bit_depth_luma = bit_depth_luma;
|
fgp->bit_depth_luma = bit_depth_luma;
|
||||||
h274->bit_depth_chroma = bit_depth_chroma;
|
fgp->bit_depth_chroma = bit_depth_chroma;
|
||||||
if (vui->video_signal_type_present_flag)
|
if (vui->video_signal_type_present_flag)
|
||||||
h274->color_range = vui->video_full_range_flag + 1;
|
fgp->color_range = vui->video_full_range_flag + 1;
|
||||||
else
|
|
||||||
h274->color_range = AVCOL_RANGE_UNSPECIFIED;
|
|
||||||
if (vui->colour_description_present_flag) {
|
if (vui->colour_description_present_flag) {
|
||||||
h274->color_primaries = vui->colour_primaries;
|
fgp->color_primaries = vui->colour_primaries;
|
||||||
h274->color_trc = vui->transfer_characteristics;
|
fgp->color_trc = vui->transfer_characteristics;
|
||||||
h274->color_space = vui->matrix_coeffs;
|
fgp->color_space = vui->matrix_coeffs;
|
||||||
} else {
|
|
||||||
h274->color_primaries = AVCOL_PRI_UNSPECIFIED;
|
|
||||||
h274->color_trc = AVCOL_TRC_UNSPECIFIED;
|
|
||||||
h274->color_space = AVCOL_SPC_UNSPECIFIED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h274->blending_mode_id = fgc->blending_mode_id;
|
h274->blending_mode_id = fgc->blending_mode_id;
|
||||||
h274->log2_scale_factor = fgc->log2_scale_factor;
|
h274->log2_scale_factor = fgc->log2_scale_factor;
|
||||||
|
|
||||||
|
#if FF_API_H274_FILM_GRAIN_VCS
|
||||||
|
FF_DISABLE_DEPRECATION_WARNINGS
|
||||||
|
h274->bit_depth_luma = fgp->bit_depth_luma;
|
||||||
|
h274->bit_depth_chroma = fgp->bit_depth_chroma;
|
||||||
|
h274->color_range = fgp->color_range;
|
||||||
|
h274->color_primaries = fgp->color_primaries;
|
||||||
|
h274->color_trc = fgp->color_trc;
|
||||||
|
h274->color_space = fgp->color_space;
|
||||||
|
FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
memcpy(&h274->component_model_present, &fgc->comp_model_present_flag,
|
memcpy(&h274->component_model_present, &fgc->comp_model_present_flag,
|
||||||
sizeof(h274->component_model_present));
|
sizeof(h274->component_model_present));
|
||||||
memcpy(&h274->num_intensity_intervals, &fgc->num_intensity_intervals,
|
memcpy(&h274->num_intensity_intervals, &fgc->num_intensity_intervals,
|
||||||
|
@ -692,6 +722,12 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
|
||||||
avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
|
avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_HEVC_SEI
|
||||||
|
ret = ff_aom_attach_film_grain_sets(&sei->aom_film_grain, frame);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sei->ambient_viewing_environment.present) {
|
if (sei->ambient_viewing_environment.present) {
|
||||||
H2645SEIAmbientViewingEnvironment *env =
|
H2645SEIAmbientViewingEnvironment *env =
|
||||||
&sei->ambient_viewing_environment;
|
&sei->ambient_viewing_environment;
|
||||||
|
@ -788,4 +824,5 @@ void ff_h2645_sei_reset(H2645SEI *s)
|
||||||
s->ambient_viewing_environment.present = 0;
|
s->ambient_viewing_environment.present = 0;
|
||||||
s->mastering_display.present = 0;
|
s->mastering_display.present = 0;
|
||||||
s->content_light.present = 0;
|
s->content_light.present = 0;
|
||||||
|
s->aom_film_grain.enable = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,9 @@
|
||||||
|
|
||||||
#include "libavutil/buffer.h"
|
#include "libavutil/buffer.h"
|
||||||
#include "libavutil/frame.h"
|
#include "libavutil/frame.h"
|
||||||
|
#include "libavutil/film_grain_params.h"
|
||||||
|
|
||||||
|
#include "aom_film_grain.h"
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "bytestream.h"
|
#include "bytestream.h"
|
||||||
#include "codec_id.h"
|
#include "codec_id.h"
|
||||||
|
@ -132,6 +134,7 @@ typedef struct H2645SEI {
|
||||||
H2645SEIAmbientViewingEnvironment ambient_viewing_environment;
|
H2645SEIAmbientViewingEnvironment ambient_viewing_environment;
|
||||||
H2645SEIMasteringDisplay mastering_display;
|
H2645SEIMasteringDisplay mastering_display;
|
||||||
H2645SEIContentLight content_light;
|
H2645SEIContentLight content_light;
|
||||||
|
AVFilmGrainAFGS1Params aom_film_grain;
|
||||||
} H2645SEI;
|
} H2645SEI;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -60,11 +60,13 @@ typedef struct H264ParseContext {
|
||||||
int nal_length_size;
|
int nal_length_size;
|
||||||
int got_first;
|
int got_first;
|
||||||
int picture_structure;
|
int picture_structure;
|
||||||
uint8_t parse_history[6];
|
uint8_t parse_history[9];
|
||||||
int parse_history_count;
|
int parse_history_count;
|
||||||
int parse_last_mb;
|
int parse_last_mb;
|
||||||
int64_t reference_dts;
|
int64_t reference_dts;
|
||||||
int last_frame_num, last_picture_structure;
|
int last_frame_num, last_picture_structure;
|
||||||
|
int is_mvc;
|
||||||
|
int slice_ext;
|
||||||
} H264ParseContext;
|
} H264ParseContext;
|
||||||
|
|
||||||
static int find_start_code(const uint8_t *buf, int buf_size,
|
static int find_start_code(const uint8_t *buf, int buf_size,
|
||||||
|
@ -122,14 +124,17 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf,
|
||||||
} else if (state <= 5) {
|
} else if (state <= 5) {
|
||||||
int nalu_type = buf[i] & 0x1F;
|
int nalu_type = buf[i] & 0x1F;
|
||||||
if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS ||
|
if (nalu_type == H264_NAL_SEI || nalu_type == H264_NAL_SPS ||
|
||||||
nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD) {
|
nalu_type == H264_NAL_PPS || nalu_type == H264_NAL_AUD ||
|
||||||
|
nalu_type == H264_NAL_SUB_SPS) {
|
||||||
if (pc->frame_start_found) {
|
if (pc->frame_start_found) {
|
||||||
i++;
|
i++;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
} else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA ||
|
} else if (nalu_type == H264_NAL_SLICE || nalu_type == H264_NAL_DPA ||
|
||||||
nalu_type == H264_NAL_IDR_SLICE) {
|
nalu_type == H264_NAL_IDR_SLICE || (p->is_mvc && nalu_type == H264_NAL_EXTEN_SLICE)) {
|
||||||
state += 8;
|
state += 8;
|
||||||
|
|
||||||
|
p->slice_ext = (nalu_type == H264_NAL_EXTEN_SLICE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
state = 7;
|
state = 7;
|
||||||
|
@ -138,20 +143,22 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf,
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
p->parse_history[p->parse_history_count++] = buf[i];
|
p->parse_history[p->parse_history_count++] = buf[i];
|
||||||
|
|
||||||
init_get_bits(&gb, p->parse_history, 8*p->parse_history_count);
|
if (!p->slice_ext || p->parse_history_count > 3) {
|
||||||
mb= get_ue_golomb_long(&gb);
|
init_get_bits8(&gb, p->parse_history + 3*p->slice_ext, p->parse_history_count - 3*p->slice_ext);
|
||||||
if (get_bits_left(&gb) > 0 || p->parse_history_count > 5) {
|
mb= get_ue_golomb_long(&gb);
|
||||||
p->parse_last_mb = mb;
|
if (get_bits_left(&gb) > 0 || p->parse_history_count > (5 + 3*p->slice_ext)) {
|
||||||
if (pc->frame_start_found) {
|
p->parse_last_mb = mb;
|
||||||
if (mb <= last_mb) {
|
if (pc->frame_start_found) {
|
||||||
i -= p->parse_history_count - 1;
|
if (mb <= last_mb) {
|
||||||
p->parse_history_count = 0;
|
i -= p->parse_history_count - 1;
|
||||||
goto found;
|
p->parse_history_count = 0;
|
||||||
}
|
goto found;
|
||||||
} else
|
}
|
||||||
pc->frame_start_found = 1;
|
} else
|
||||||
p->parse_history_count = 0;
|
pc->frame_start_found = 1;
|
||||||
state = 7;
|
p->parse_history_count = 0;
|
||||||
|
state = 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,6 +612,9 @@ static int h264_parse(AVCodecParserContext *s,
|
||||||
} else {
|
} else {
|
||||||
next = h264_find_frame_end(p, buf, buf_size, avctx);
|
next = h264_find_frame_end(p, buf, buf_size, avctx);
|
||||||
|
|
||||||
|
if (next == END_NOT_FOUND && pc->frame_start_found == 0)
|
||||||
|
s->fetch_timestamp = 1;
|
||||||
|
|
||||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||||
*poutbuf = NULL;
|
*poutbuf = NULL;
|
||||||
*poutbuf_size = 0;
|
*poutbuf_size = 0;
|
||||||
|
@ -617,7 +627,8 @@ static int h264_parse(AVCodecParserContext *s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_nal_units(s, avctx, buf, buf_size);
|
if (!p->is_mvc)
|
||||||
|
parse_nal_units(s, avctx, buf, buf_size);
|
||||||
|
|
||||||
if (avctx->framerate.num)
|
if (avctx->framerate.num)
|
||||||
time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){2, 1}));
|
time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){2, 1}));
|
||||||
|
@ -688,3 +699,22 @@ const AVCodecParser ff_h264_parser = {
|
||||||
.parser_parse = h264_parse,
|
.parser_parse = h264_parse,
|
||||||
.parser_close = h264_close,
|
.parser_close = h264_close,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static av_cold int init_mvc(AVCodecParserContext *s)
|
||||||
|
{
|
||||||
|
H264ParseContext *p = s->priv_data;
|
||||||
|
int ret = init(s);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
p->is_mvc = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVCodecParser ff_h264_mvc_parser = {
|
||||||
|
.codec_ids = { AV_CODEC_ID_H264_MVC },
|
||||||
|
.priv_data_size = sizeof(H264ParseContext),
|
||||||
|
.parser_init = init_mvc,
|
||||||
|
.parser_parse = h264_parse,
|
||||||
|
.parser_close = h264_close,
|
||||||
|
};
|
||||||
|
|
|
@ -470,6 +470,7 @@ int ff_h264_update_thread_context_for_user(AVCodecContext *dst,
|
||||||
|
|
||||||
h->is_avc = h1->is_avc;
|
h->is_avc = h1->is_avc;
|
||||||
h->nal_length_size = h1->nal_length_size;
|
h->nal_length_size = h1->nal_length_size;
|
||||||
|
h->x264_build = h1->x264_build;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -866,14 +867,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||||
if (CHROMA444(h)) {
|
if (CHROMA444(h)) {
|
||||||
if (h->avctx->colorspace == AVCOL_SPC_RGB)
|
if (h->avctx->colorspace == AVCOL_SPC_RGB)
|
||||||
*fmt++ = AV_PIX_FMT_GBRP;
|
*fmt++ = AV_PIX_FMT_GBRP;
|
||||||
else if (h->avctx->color_range == AVCOL_RANGE_JPEG)
|
|
||||||
*fmt++ = AV_PIX_FMT_YUVJ444P;
|
|
||||||
else
|
else
|
||||||
*fmt++ = AV_PIX_FMT_YUV444P;
|
*fmt++ = AV_PIX_FMT_YUV444P;
|
||||||
} else if (CHROMA422(h)) {
|
} else if (CHROMA422(h)) {
|
||||||
if (h->avctx->color_range == AVCOL_RANGE_JPEG)
|
|
||||||
*fmt++ = AV_PIX_FMT_YUVJ422P;
|
|
||||||
else
|
|
||||||
*fmt++ = AV_PIX_FMT_YUV422P;
|
*fmt++ = AV_PIX_FMT_YUV422P;
|
||||||
} else {
|
} else {
|
||||||
#if CONFIG_H264_DXVA2_HWACCEL
|
#if CONFIG_H264_DXVA2_HWACCEL
|
||||||
|
@ -889,9 +885,6 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||||
#if CONFIG_H264_VAAPI_HWACCEL
|
#if CONFIG_H264_VAAPI_HWACCEL
|
||||||
*fmt++ = AV_PIX_FMT_VAAPI;
|
*fmt++ = AV_PIX_FMT_VAAPI;
|
||||||
#endif
|
#endif
|
||||||
if (h->avctx->color_range == AVCOL_RANGE_JPEG)
|
|
||||||
*fmt++ = AV_PIX_FMT_YUVJ420P;
|
|
||||||
else
|
|
||||||
*fmt++ = AV_PIX_FMT_YUV420P;
|
*fmt++ = AV_PIX_FMT_YUV420P;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -909,6 +902,11 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
|
||||||
return ff_get_format(h->avctx, pix_fmts);
|
return ff_get_format(h->avctx, pix_fmts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum AVPixelFormat ff_h264_get_pixel_format(H264Context *h)
|
||||||
|
{
|
||||||
|
return get_pixel_format(h, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* export coded and cropped frame dimensions to AVCodecContext */
|
/* export coded and cropped frame dimensions to AVCodecContext */
|
||||||
static void init_dimensions(H264Context *h)
|
static void init_dimensions(H264Context *h)
|
||||||
{
|
{
|
||||||
|
@ -1086,6 +1084,7 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_sl
|
||||||
h->avctx->profile = ff_h264_get_profile(sps);
|
h->avctx->profile = ff_h264_get_profile(sps);
|
||||||
h->avctx->level = sps->level_idc;
|
h->avctx->level = sps->level_idc;
|
||||||
h->avctx->refs = sps->ref_frame_count;
|
h->avctx->refs = sps->ref_frame_count;
|
||||||
|
h->avctx->progressive_sequence = sps->frame_mbs_only_flag;
|
||||||
|
|
||||||
h->mb_width = sps->mb_width;
|
h->mb_width = sps->mb_width;
|
||||||
h->mb_height = sps->mb_height;
|
h->mb_height = sps->mb_height;
|
||||||
|
@ -1185,6 +1184,7 @@ static int h264_export_frame_props(H264Context *h)
|
||||||
const H264SEIPictureTiming *pt = &h->sei.picture_timing;
|
const H264SEIPictureTiming *pt = &h->sei.picture_timing;
|
||||||
switch (pt->pic_struct) {
|
switch (pt->pic_struct) {
|
||||||
case H264_SEI_PIC_STRUCT_FRAME:
|
case H264_SEI_PIC_STRUCT_FRAME:
|
||||||
|
interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
|
||||||
break;
|
break;
|
||||||
case H264_SEI_PIC_STRUCT_TOP_FIELD:
|
case H264_SEI_PIC_STRUCT_TOP_FIELD:
|
||||||
case H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
|
case H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
|
||||||
|
|
|
@ -417,6 +417,28 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* activate the first SPS to determine basic stream information */
|
||||||
|
if (!h->ps.sps) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list) && !h->ps.sps; i++) {
|
||||||
|
if (h->ps.pps_list[i]) {
|
||||||
|
ff_refstruct_replace(&h->ps.pps, h->ps.pps_list[i]);
|
||||||
|
h->ps.sps = h->ps.pps->sps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->ps.sps) {
|
||||||
|
h->avctx->colorspace = h->ps.sps->vui.matrix_coeffs;
|
||||||
|
h->avctx->pix_fmt = ff_h264_get_pixel_format(h);
|
||||||
|
if (h->avctx->pix_fmt < 0)
|
||||||
|
h->avctx->pix_fmt = AV_PIX_FMT_NONE;
|
||||||
|
|
||||||
|
h->avctx->profile = ff_h264_get_profile(h->ps.sps);
|
||||||
|
h->avctx->level = h->ps.sps->level_idc;
|
||||||
|
h->avctx->refs = h->ps.sps->ref_frame_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->ps.sps && h->ps.sps->bitstream_restriction_flag &&
|
if (h->ps.sps && h->ps.sps->bitstream_restriction_flag &&
|
||||||
|
@ -497,9 +519,6 @@ static void h264_decode_flush(AVCodecContext *avctx)
|
||||||
h->mb_y = 0;
|
h->mb_y = 0;
|
||||||
h->non_gray = 0;
|
h->non_gray = 0;
|
||||||
|
|
||||||
ff_h264_free_tables(h);
|
|
||||||
h->context_initialized = 0;
|
|
||||||
|
|
||||||
if (FF_HW_HAS_CB(avctx, flush))
|
if (FF_HW_HAS_CB(avctx, flush))
|
||||||
FF_HW_SIMPLE_CALL(avctx, flush);
|
FF_HW_SIMPLE_CALL(avctx, flush);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
* The maximum number of slices supported by the decoder.
|
* The maximum number of slices supported by the decoder.
|
||||||
* must be a power of 2
|
* must be a power of 2
|
||||||
*/
|
*/
|
||||||
#define MAX_SLICES 32
|
#define MAX_SLICES 256
|
||||||
|
|
||||||
#ifdef ALLOW_INTERLACE
|
#ifdef ALLOW_INTERLACE
|
||||||
#define MB_MBAFF(h) (h)->mb_mbaff
|
#define MB_MBAFF(h) (h)->mb_mbaff
|
||||||
|
@ -699,4 +699,6 @@ void ff_h264_free_tables(H264Context *h);
|
||||||
|
|
||||||
void ff_h264_set_erpic(ERPicture *dst, const H264Picture *src);
|
void ff_h264_set_erpic(ERPicture *dst, const H264Picture *src);
|
||||||
|
|
||||||
|
enum AVPixelFormat ff_h264_get_pixel_format(H264Context *h);
|
||||||
|
|
||||||
#endif /* AVCODEC_H264DEC_H */
|
#endif /* AVCODEC_H264DEC_H */
|
||||||
|
|
|
@ -370,7 +370,7 @@ static void decode_sublayer_hrd(GetBitContext *gb, unsigned int nb_cpb,
|
||||||
par->bit_rate_du_value_minus1[i] = get_ue_golomb_long(gb);
|
par->bit_rate_du_value_minus1[i] = get_ue_golomb_long(gb);
|
||||||
}
|
}
|
||||||
|
|
||||||
par->cbr_flag = get_bits1(gb);
|
par->cbr_flag |= get_bits1(gb) << i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,24 +378,24 @@ static int decode_hrd(GetBitContext *gb, int common_inf_present,
|
||||||
HEVCHdrParams *hdr, int max_sublayers)
|
HEVCHdrParams *hdr, int max_sublayers)
|
||||||
{
|
{
|
||||||
if (common_inf_present) {
|
if (common_inf_present) {
|
||||||
hdr->flags.nal_hrd_parameters_present_flag = get_bits1(gb);
|
hdr->nal_hrd_parameters_present_flag = get_bits1(gb);
|
||||||
hdr->flags.vcl_hrd_parameters_present_flag = get_bits1(gb);
|
hdr->vcl_hrd_parameters_present_flag = get_bits1(gb);
|
||||||
|
|
||||||
if (hdr->flags.nal_hrd_parameters_present_flag ||
|
if (hdr->nal_hrd_parameters_present_flag ||
|
||||||
hdr->flags.vcl_hrd_parameters_present_flag) {
|
hdr->vcl_hrd_parameters_present_flag) {
|
||||||
hdr->flags.sub_pic_hrd_params_present_flag = get_bits1(gb);
|
hdr->sub_pic_hrd_params_present_flag = get_bits1(gb);
|
||||||
|
|
||||||
if (hdr->flags.sub_pic_hrd_params_present_flag) {
|
if (hdr->sub_pic_hrd_params_present_flag) {
|
||||||
hdr->tick_divisor_minus2 = get_bits(gb, 8);
|
hdr->tick_divisor_minus2 = get_bits(gb, 8);
|
||||||
hdr->du_cpb_removal_delay_increment_length_minus1 = get_bits(gb, 5);
|
hdr->du_cpb_removal_delay_increment_length_minus1 = get_bits(gb, 5);
|
||||||
hdr->flags.sub_pic_cpb_params_in_pic_timing_sei_flag = get_bits1(gb);
|
hdr->sub_pic_cpb_params_in_pic_timing_sei_flag = get_bits1(gb);
|
||||||
hdr->dpb_output_delay_du_length_minus1 = get_bits(gb, 5);
|
hdr->dpb_output_delay_du_length_minus1 = get_bits(gb, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr->bit_rate_scale = get_bits(gb, 4);
|
hdr->bit_rate_scale = get_bits(gb, 4);
|
||||||
hdr->cpb_size_scale = get_bits(gb, 4);
|
hdr->cpb_size_scale = get_bits(gb, 4);
|
||||||
|
|
||||||
if (hdr->flags.sub_pic_hrd_params_present_flag)
|
if (hdr->sub_pic_hrd_params_present_flag)
|
||||||
hdr->cpb_size_du_scale = get_bits(gb, 4);
|
hdr->cpb_size_du_scale = get_bits(gb, 4);
|
||||||
|
|
||||||
hdr->initial_cpb_removal_delay_length_minus1 = get_bits(gb, 5);
|
hdr->initial_cpb_removal_delay_length_minus1 = get_bits(gb, 5);
|
||||||
|
@ -405,18 +405,22 @@ static int decode_hrd(GetBitContext *gb, int common_inf_present,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < max_sublayers; i++) {
|
for (int i = 0; i < max_sublayers; i++) {
|
||||||
hdr->flags.fixed_pic_rate_general_flag = get_bits1(gb);
|
unsigned fixed_pic_rate_general_flag = get_bits1(gb);
|
||||||
|
unsigned fixed_pic_rate_within_cvs_flag = 0;
|
||||||
|
unsigned low_delay_hrd_flag = 0;
|
||||||
|
hdr->flags.fixed_pic_rate_general_flag |= fixed_pic_rate_general_flag << i;
|
||||||
|
|
||||||
if (!hdr->flags.fixed_pic_rate_general_flag)
|
if (!fixed_pic_rate_general_flag)
|
||||||
hdr->flags.fixed_pic_rate_within_cvs_flag = get_bits1(gb);
|
fixed_pic_rate_within_cvs_flag = get_bits1(gb);
|
||||||
|
hdr->flags.fixed_pic_rate_within_cvs_flag |= fixed_pic_rate_within_cvs_flag << i;
|
||||||
|
|
||||||
if (hdr->flags.fixed_pic_rate_within_cvs_flag ||
|
if (fixed_pic_rate_within_cvs_flag || fixed_pic_rate_general_flag)
|
||||||
hdr->flags.fixed_pic_rate_general_flag)
|
|
||||||
hdr->elemental_duration_in_tc_minus1[i] = get_ue_golomb_long(gb);
|
hdr->elemental_duration_in_tc_minus1[i] = get_ue_golomb_long(gb);
|
||||||
else
|
else
|
||||||
hdr->flags.low_delay_hrd_flag = get_bits1(gb);
|
low_delay_hrd_flag = get_bits1(gb);
|
||||||
|
hdr->flags.low_delay_hrd_flag |= low_delay_hrd_flag << i;
|
||||||
|
|
||||||
if (!hdr->flags.low_delay_hrd_flag) {
|
if (!low_delay_hrd_flag) {
|
||||||
unsigned cpb_cnt_minus1 = get_ue_golomb_long(gb);
|
unsigned cpb_cnt_minus1 = get_ue_golomb_long(gb);
|
||||||
if (cpb_cnt_minus1 > 31) {
|
if (cpb_cnt_minus1 > 31) {
|
||||||
av_log(NULL, AV_LOG_ERROR, "nb_cpb %d invalid\n",
|
av_log(NULL, AV_LOG_ERROR, "nb_cpb %d invalid\n",
|
||||||
|
@ -426,25 +430,32 @@ static int decode_hrd(GetBitContext *gb, int common_inf_present,
|
||||||
hdr->cpb_cnt_minus1[i] = cpb_cnt_minus1;
|
hdr->cpb_cnt_minus1[i] = cpb_cnt_minus1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr->flags.nal_hrd_parameters_present_flag)
|
if (hdr->nal_hrd_parameters_present_flag)
|
||||||
decode_sublayer_hrd(gb, hdr->cpb_cnt_minus1[i]+1, &hdr->nal_params[i],
|
decode_sublayer_hrd(gb, hdr->cpb_cnt_minus1[i]+1, &hdr->nal_params[i],
|
||||||
hdr->flags.sub_pic_hrd_params_present_flag);
|
hdr->sub_pic_hrd_params_present_flag);
|
||||||
|
|
||||||
if (hdr->flags.vcl_hrd_parameters_present_flag)
|
if (hdr->vcl_hrd_parameters_present_flag)
|
||||||
decode_sublayer_hrd(gb, hdr->cpb_cnt_minus1[i]+1, &hdr->vcl_params[i],
|
decode_sublayer_hrd(gb, hdr->cpb_cnt_minus1[i]+1, &hdr->vcl_params[i],
|
||||||
hdr->flags.sub_pic_hrd_params_present_flag);
|
hdr->sub_pic_hrd_params_present_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uninit_vps(FFRefStructOpaque opaque, void *obj)
|
||||||
|
{
|
||||||
|
HEVCVPS *vps = obj;
|
||||||
|
|
||||||
|
av_freep(&vps->hdr);
|
||||||
|
}
|
||||||
|
|
||||||
int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
|
int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
|
||||||
HEVCParamSets *ps)
|
HEVCParamSets *ps)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
int vps_id = 0;
|
int vps_id = 0;
|
||||||
ptrdiff_t nal_size;
|
ptrdiff_t nal_size;
|
||||||
HEVCVPS *vps = ff_refstruct_allocz(sizeof(*vps));
|
HEVCVPS *vps = ff_refstruct_alloc_ext(sizeof(*vps), 0, NULL, uninit_vps);
|
||||||
|
|
||||||
if (!vps)
|
if (!vps)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
@ -533,6 +544,11 @@ int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
|
||||||
"vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters);
|
"vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vps->hdr = av_calloc(vps->vps_num_hrd_parameters, sizeof(*vps->hdr));
|
||||||
|
if (!vps->hdr)
|
||||||
|
goto err;
|
||||||
|
|
||||||
for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
|
for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
|
||||||
int common_inf_present = 1;
|
int common_inf_present = 1;
|
||||||
|
|
||||||
|
@ -577,8 +593,6 @@ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
|
||||||
ff_h2645_decode_common_vui_params(gb, &sps->vui.common, avctx);
|
ff_h2645_decode_common_vui_params(gb, &sps->vui.common, avctx);
|
||||||
|
|
||||||
if (vui->common.video_signal_type_present_flag) {
|
if (vui->common.video_signal_type_present_flag) {
|
||||||
if (vui->common.video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
|
|
||||||
sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
|
|
||||||
if (vui->common.colour_description_present_flag) {
|
if (vui->common.colour_description_present_flag) {
|
||||||
if (vui->common.matrix_coeffs == AVCOL_SPC_RGB) {
|
if (vui->common.matrix_coeffs == AVCOL_SPC_RGB) {
|
||||||
switch (sps->pix_fmt) {
|
switch (sps->pix_fmt) {
|
||||||
|
|
|
@ -39,18 +39,19 @@ typedef struct HEVCSublayerHdrParams {
|
||||||
uint32_t cbr_flag;
|
uint32_t cbr_flag;
|
||||||
} HEVCSublayerHdrParams;
|
} HEVCSublayerHdrParams;
|
||||||
|
|
||||||
|
// flags in bitmask form
|
||||||
typedef struct HEVCHdrFlagParams {
|
typedef struct HEVCHdrFlagParams {
|
||||||
uint32_t nal_hrd_parameters_present_flag;
|
uint8_t fixed_pic_rate_general_flag;
|
||||||
uint32_t vcl_hrd_parameters_present_flag;
|
uint8_t fixed_pic_rate_within_cvs_flag;
|
||||||
uint32_t sub_pic_hrd_params_present_flag;
|
uint8_t low_delay_hrd_flag;
|
||||||
uint32_t sub_pic_cpb_params_in_pic_timing_sei_flag;
|
|
||||||
uint32_t fixed_pic_rate_general_flag;
|
|
||||||
uint32_t fixed_pic_rate_within_cvs_flag;
|
|
||||||
uint32_t low_delay_hrd_flag;
|
|
||||||
} HEVCHdrFlagParams;
|
} HEVCHdrFlagParams;
|
||||||
|
|
||||||
typedef struct HEVCHdrParams {
|
typedef struct HEVCHdrParams {
|
||||||
HEVCHdrFlagParams flags;
|
HEVCHdrFlagParams flags;
|
||||||
|
uint8_t nal_hrd_parameters_present_flag;
|
||||||
|
uint8_t vcl_hrd_parameters_present_flag;
|
||||||
|
uint8_t sub_pic_hrd_params_present_flag;
|
||||||
|
uint8_t sub_pic_cpb_params_in_pic_timing_sei_flag;
|
||||||
|
|
||||||
uint8_t tick_divisor_minus2;
|
uint8_t tick_divisor_minus2;
|
||||||
uint8_t du_cpb_removal_delay_increment_length_minus1;
|
uint8_t du_cpb_removal_delay_increment_length_minus1;
|
||||||
|
@ -152,7 +153,7 @@ typedef struct PTL {
|
||||||
|
|
||||||
typedef struct HEVCVPS {
|
typedef struct HEVCVPS {
|
||||||
unsigned int vps_id;
|
unsigned int vps_id;
|
||||||
HEVCHdrParams hdr[HEVC_MAX_LAYER_SETS];
|
HEVCHdrParams *hdr;
|
||||||
|
|
||||||
uint8_t vps_temporal_id_nesting_flag;
|
uint8_t vps_temporal_id_nesting_flag;
|
||||||
int vps_max_layers;
|
int vps_max_layers;
|
||||||
|
|
|
@ -50,6 +50,8 @@ void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
|
||||||
frame->refPicList = NULL;
|
frame->refPicList = NULL;
|
||||||
|
|
||||||
ff_refstruct_unref(&frame->hwaccel_picture_private);
|
ff_refstruct_unref(&frame->hwaccel_picture_private);
|
||||||
|
|
||||||
|
frame->missing = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +442,7 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
|
||||||
frame->poc = poc;
|
frame->poc = poc;
|
||||||
frame->sequence = HEVC_SEQUENCE_COUNTER_INVALID;
|
frame->sequence = HEVC_SEQUENCE_COUNTER_INVALID;
|
||||||
frame->flags = 0;
|
frame->flags = 0;
|
||||||
|
frame->missing = 1;
|
||||||
|
|
||||||
if (s->threads_type == FF_THREAD_FRAME)
|
if (s->threads_type == FF_THREAD_FRAME)
|
||||||
ff_thread_report_progress(&frame->tf, INT_MAX, 0);
|
ff_thread_report_progress(&frame->tf, INT_MAX, 0);
|
||||||
|
|
|
@ -29,12 +29,14 @@
|
||||||
#include "libavutil/avstring.h"
|
#include "libavutil/avstring.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/film_grain_params.h"
|
#include "libavutil/film_grain_params.h"
|
||||||
|
#include "libavutil/hdr_dynamic_metadata.h"
|
||||||
#include "libavutil/internal.h"
|
#include "libavutil/internal.h"
|
||||||
#include "libavutil/md5.h"
|
#include "libavutil/md5.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "libavutil/timecode.h"
|
#include "libavutil/timecode.h"
|
||||||
|
|
||||||
|
#include "aom_film_grain.h"
|
||||||
#include "bswapdsp.h"
|
#include "bswapdsp.h"
|
||||||
#include "cabac_functions.h"
|
#include "cabac_functions.h"
|
||||||
#include "codec_internal.h"
|
#include "codec_internal.h"
|
||||||
|
@ -388,7 +390,8 @@ static int export_stream_params_from_sei(HEVCContext *s)
|
||||||
avctx->color_trc = s->sei.common.alternative_transfer.preferred_transfer_characteristics;
|
avctx->color_trc = s->sei.common.alternative_transfer.preferred_transfer_characteristics;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->sei.common.film_grain_characteristics.present)
|
if (s->sei.common.film_grain_characteristics.present ||
|
||||||
|
s->sei.common.aom_film_grain.enable)
|
||||||
avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
|
avctx->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2815,7 +2818,30 @@ static int set_side_data(HEVCContext *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->sei.common.dynamic_hdr_plus.info) {
|
if (s->sei.common.dynamic_hdr_plus.info) {
|
||||||
AVBufferRef *info_ref = av_buffer_ref(s->sei.common.dynamic_hdr_plus.info);
|
AVBufferRef *info_ref;
|
||||||
|
AVDynamicHDRPlus *metadata = (AVDynamicHDRPlus*)s->sei.common.dynamic_hdr_plus.info->data;
|
||||||
|
|
||||||
|
// fill in window 0 (full frame) and convert to relative coordinates
|
||||||
|
if (metadata->params[0].window_lower_right_corner_x.num == 0)
|
||||||
|
{
|
||||||
|
// ensure the buffer is writable
|
||||||
|
av_buffer_make_writable(&s->sei.common.dynamic_hdr_plus.info);
|
||||||
|
metadata = (AVDynamicHDRPlus*)s->sei.common.dynamic_hdr_plus.info->data;
|
||||||
|
|
||||||
|
// Convert coordinates to relative coordinate in [0, 1].
|
||||||
|
metadata->params[0].window_upper_left_corner_x.num = 0;
|
||||||
|
metadata->params[0].window_upper_left_corner_y.num = 0;
|
||||||
|
metadata->params[0].window_lower_right_corner_x.num = out->width - 1;
|
||||||
|
metadata->params[0].window_lower_right_corner_y.num = out->height - 1;
|
||||||
|
for (int w = 0; w < metadata->num_windows; w++) {
|
||||||
|
metadata->params[w].window_upper_left_corner_x.den = out->width - 1;
|
||||||
|
metadata->params[w].window_upper_left_corner_y.den = out->height - 1;
|
||||||
|
metadata->params[w].window_lower_right_corner_x.den = out->width - 1;
|
||||||
|
metadata->params[w].window_lower_right_corner_y.den = out->height - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info_ref = av_buffer_ref(s->sei.common.dynamic_hdr_plus.info);
|
||||||
if (!info_ref)
|
if (!info_ref)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
@ -2885,11 +2911,13 @@ static int hevc_frame_start(HEVCContext *s)
|
||||||
else
|
else
|
||||||
s->ref->frame->flags &= ~AV_FRAME_FLAG_KEY;
|
s->ref->frame->flags &= ~AV_FRAME_FLAG_KEY;
|
||||||
|
|
||||||
s->ref->needs_fg = s->sei.common.film_grain_characteristics.present &&
|
s->ref->needs_fg = (s->sei.common.film_grain_characteristics.present ||
|
||||||
|
s->sei.common.aom_film_grain.enable) &&
|
||||||
!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
|
!(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
|
||||||
!s->avctx->hwaccel;
|
!s->avctx->hwaccel;
|
||||||
|
|
||||||
if (s->ref->needs_fg &&
|
if (s->ref->needs_fg &&
|
||||||
|
s->sei.common.film_grain_characteristics.present &&
|
||||||
!ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics.model_id,
|
!ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics.model_id,
|
||||||
s->ref->frame->format)) {
|
s->ref->frame->format)) {
|
||||||
av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, &s->film_grain_warning_shown,
|
av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, &s->film_grain_warning_shown,
|
||||||
|
@ -2934,14 +2962,24 @@ fail:
|
||||||
static int hevc_frame_end(HEVCContext *s)
|
static int hevc_frame_end(HEVCContext *s)
|
||||||
{
|
{
|
||||||
HEVCFrame *out = s->ref;
|
HEVCFrame *out = s->ref;
|
||||||
const AVFrameSideData *sd;
|
const AVFilmGrainParams *fgp;
|
||||||
av_unused int ret;
|
av_unused int ret;
|
||||||
|
|
||||||
if (out->needs_fg) {
|
if (out->needs_fg) {
|
||||||
sd = av_frame_get_side_data(out->frame, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
|
av_assert0(out->frame_grain->buf[0]);
|
||||||
av_assert0(out->frame_grain->buf[0] && sd);
|
fgp = av_film_grain_params_select(out->frame);
|
||||||
ret = ff_h274_apply_film_grain(out->frame_grain, out->frame, &s->h274db,
|
switch (fgp->type) {
|
||||||
(AVFilmGrainParams *) sd->data);
|
case AV_FILM_GRAIN_PARAMS_NONE:
|
||||||
|
av_assert0(0);
|
||||||
|
return AVERROR_BUG;
|
||||||
|
case AV_FILM_GRAIN_PARAMS_H274:
|
||||||
|
ret = ff_h274_apply_film_grain(out->frame_grain, out->frame,
|
||||||
|
&s->h274db, fgp);
|
||||||
|
break;
|
||||||
|
case AV_FILM_GRAIN_PARAMS_AV1:
|
||||||
|
ret = ff_aom_apply_film_grain(out->frame_grain, out->frame, fgp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
av_assert1(ret >= 0);
|
av_assert1(ret >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3596,6 +3634,7 @@ static int hevc_update_thread_context(AVCodecContext *dst,
|
||||||
s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer;
|
s->sei.common.alternative_transfer = s0->sei.common.alternative_transfer;
|
||||||
s->sei.common.mastering_display = s0->sei.common.mastering_display;
|
s->sei.common.mastering_display = s0->sei.common.mastering_display;
|
||||||
s->sei.common.content_light = s0->sei.common.content_light;
|
s->sei.common.content_light = s0->sei.common.content_light;
|
||||||
|
s->sei.common.aom_film_grain = s0->sei.common.aom_film_grain;
|
||||||
|
|
||||||
ret = export_stream_params_from_sei(s);
|
ret = export_stream_params_from_sei(s);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -3639,7 +3678,8 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
|
||||||
if (avctx->extradata_size > 0 && avctx->extradata) {
|
if (avctx->extradata_size > 0 && avctx->extradata) {
|
||||||
ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size, 1);
|
ret = hevc_decode_extradata(s, avctx->extradata, avctx->extradata_size, 1);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
s->is_nalff = 0;
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Invalid extradata ignored\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,11 @@ typedef struct HEVCFrame {
|
||||||
* A combination of HEVC_FRAME_FLAG_*
|
* A combination of HEVC_FRAME_FLAG_*
|
||||||
*/
|
*/
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 - a dummy frame generated in place of a missing frame
|
||||||
|
*/
|
||||||
|
int missing;
|
||||||
} HEVCFrame;
|
} HEVCFrame;
|
||||||
|
|
||||||
typedef struct HEVCLocalContext {
|
typedef struct HEVCLocalContext {
|
||||||
|
|
|
@ -78,4 +78,7 @@ void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth)
|
||||||
#if ARCH_MIPS
|
#if ARCH_MIPS
|
||||||
ff_hevc_pred_init_mips(hpc, bit_depth);
|
ff_hevc_pred_init_mips(hpc, bit_depth);
|
||||||
#endif
|
#endif
|
||||||
|
#if ARCH_X86
|
||||||
|
ff_hevc_pred_init_x86(hpc, bit_depth);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,5 +42,6 @@ typedef struct HEVCPredContext {
|
||||||
|
|
||||||
void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth);
|
void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth);
|
||||||
void ff_hevc_pred_init_mips(HEVCPredContext *hpc, int bit_depth);
|
void ff_hevc_pred_init_mips(HEVCPredContext *hpc, int bit_depth);
|
||||||
|
void ff_hevc_pred_init_x86(HEVCPredContext *hpc, int bit_depth);
|
||||||
|
|
||||||
#endif /* AVCODEC_HEVCPRED_H */
|
#endif /* AVCODEC_HEVCPRED_H */
|
||||||
|
|
|
@ -64,7 +64,7 @@ void ff_hwaccel_uninit(AVCodecContext *avctx);
|
||||||
#define HWACCEL_DXVA2(codec) \
|
#define HWACCEL_DXVA2(codec) \
|
||||||
HW_CONFIG_HWACCEL(1, 1, 1, DXVA2_VLD, DXVA2, ff_ ## codec ## _dxva2_hwaccel)
|
HW_CONFIG_HWACCEL(1, 1, 1, DXVA2_VLD, DXVA2, ff_ ## codec ## _dxva2_hwaccel)
|
||||||
#define HWACCEL_D3D11VA2(codec) \
|
#define HWACCEL_D3D11VA2(codec) \
|
||||||
HW_CONFIG_HWACCEL(1, 1, 0, D3D11, D3D11VA, ff_ ## codec ## _d3d11va2_hwaccel)
|
HW_CONFIG_HWACCEL(1, 1, 1, D3D11, D3D11VA, ff_ ## codec ## _d3d11va2_hwaccel)
|
||||||
#define HWACCEL_NVDEC(codec) \
|
#define HWACCEL_NVDEC(codec) \
|
||||||
HW_CONFIG_HWACCEL(1, 1, 0, CUDA, CUDA, ff_ ## codec ## _nvdec_hwaccel)
|
HW_CONFIG_HWACCEL(1, 1, 0, CUDA, CUDA, ff_ ## codec ## _nvdec_hwaccel)
|
||||||
#define HWACCEL_VAAPI(codec) \
|
#define HWACCEL_VAAPI(codec) \
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVCODEC_ITUT35_H
|
||||||
|
#define AVCODEC_ITUT35_H
|
||||||
|
|
||||||
|
#define ITU_T_T35_COUNTRY_CODE_CN 0x26
|
||||||
|
#define ITU_T_T35_COUNTRY_CODE_US 0xB5
|
||||||
|
|
||||||
|
#define ITU_T_T35_PROVIDER_CODE_ATSC 0x31
|
||||||
|
#define ITU_T_T35_PROVIDER_CODE_CUVA 0x04
|
||||||
|
#define ITU_T_T35_PROVIDER_CODE_DOLBY 0x3B
|
||||||
|
#define ITU_T_T35_PROVIDER_CODE_SMTPE 0x3C
|
||||||
|
|
||||||
|
#endif /* AVCODEC_ITUT35_H */
|
|
@ -35,6 +35,7 @@
|
||||||
#include "ffjni.h"
|
#include "ffjni.h"
|
||||||
|
|
||||||
static void *java_vm;
|
static void *java_vm;
|
||||||
|
static void *android_app_ctx;
|
||||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
int av_jni_set_java_vm(void *vm, void *log_ctx)
|
int av_jni_set_java_vm(void *vm, void *log_ctx)
|
||||||
|
@ -77,3 +78,45 @@ void *av_jni_get_java_vm(void *log_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
|
||||||
|
int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx)
|
||||||
|
{
|
||||||
|
#if CONFIG_JNI
|
||||||
|
JNIEnv *env = ff_jni_get_env(log_ctx);
|
||||||
|
if (!env)
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
|
||||||
|
jobjectRefType type = (*env)->GetObjectRefType(env, app_ctx);
|
||||||
|
if (type != JNIGlobalRefType) {
|
||||||
|
av_log(log_ctx, AV_LOG_ERROR, "Application context must be passed as a global reference");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
android_app_ctx = app_ctx;
|
||||||
|
pthread_mutex_unlock(&lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return AVERROR(ENOSYS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void *av_jni_get_android_app_ctx(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_JNI
|
||||||
|
void *ctx;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
ctx = android_app_ctx;
|
||||||
|
pthread_mutex_unlock(&lock);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -43,4 +43,25 @@ int av_jni_set_java_vm(void *vm, void *log_ctx);
|
||||||
*/
|
*/
|
||||||
void *av_jni_get_java_vm(void *log_ctx);
|
void *av_jni_get_java_vm(void *log_ctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the Android application context which will be used to retrieve the Android
|
||||||
|
* content resolver to handle content uris.
|
||||||
|
*
|
||||||
|
* This function is only available on Android.
|
||||||
|
*
|
||||||
|
* @param app_ctx global JNI reference to the Android application context
|
||||||
|
* @return 0 on success, < 0 otherwise
|
||||||
|
*/
|
||||||
|
int av_jni_set_android_app_ctx(void *app_ctx, void *log_ctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the Android application context that has been set with
|
||||||
|
* av_jni_set_android_app_ctx.
|
||||||
|
*
|
||||||
|
* This function is only available on Android.
|
||||||
|
*
|
||||||
|
* @return a pointer the the Android application context
|
||||||
|
*/
|
||||||
|
void *av_jni_get_android_app_ctx(void);
|
||||||
|
|
||||||
#endif /* AVCODEC_JNI_H */
|
#endif /* AVCODEC_JNI_H */
|
||||||
|
|
|
@ -4,6 +4,10 @@ LIBAVCODEC_MAJOR {
|
||||||
avcodec_*;
|
avcodec_*;
|
||||||
avpriv_*;
|
avpriv_*;
|
||||||
avsubtitle_free;
|
avsubtitle_free;
|
||||||
|
#LAV usage
|
||||||
|
ff_vc1_pixel_aspect;
|
||||||
|
ff_crop_tab;
|
||||||
|
ff_flac_is_extradata_valid;
|
||||||
local:
|
local:
|
||||||
*;
|
*;
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
#include "dovi_rpu.h"
|
#include "dovi_rpu.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
#include "itut35.h"
|
||||||
|
|
||||||
#define FF_DAV1D_VERSION_AT_LEAST(x,y) \
|
#define FF_DAV1D_VERSION_AT_LEAST(x,y) \
|
||||||
(DAV1D_API_VERSION_MAJOR > (x) || DAV1D_API_VERSION_MAJOR == (x) && DAV1D_API_VERSION_MINOR >= (y))
|
(DAV1D_API_VERSION_MAJOR > (x) || DAV1D_API_VERSION_MAJOR == (x) && DAV1D_API_VERSION_MINOR >= (y))
|
||||||
|
@ -304,10 +305,6 @@ static void libdav1d_flush(AVCodecContext *c)
|
||||||
dav1d_flush(dav1d->c);
|
dav1d_flush(dav1d->c);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct OpaqueData {
|
|
||||||
void *pkt_orig_opaque;
|
|
||||||
} OpaqueData;
|
|
||||||
|
|
||||||
static void libdav1d_data_free(const uint8_t *data, void *opaque) {
|
static void libdav1d_data_free(const uint8_t *data, void *opaque) {
|
||||||
AVBufferRef *buf = opaque;
|
AVBufferRef *buf = opaque;
|
||||||
|
|
||||||
|
@ -317,7 +314,6 @@ static void libdav1d_data_free(const uint8_t *data, void *opaque) {
|
||||||
static void libdav1d_user_data_free(const uint8_t *data, void *opaque) {
|
static void libdav1d_user_data_free(const uint8_t *data, void *opaque) {
|
||||||
AVPacket *pkt = opaque;
|
AVPacket *pkt = opaque;
|
||||||
av_assert0(data == opaque);
|
av_assert0(data == opaque);
|
||||||
av_free(pkt->opaque);
|
|
||||||
av_packet_free(&pkt);
|
av_packet_free(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,8 +336,6 @@ static int libdav1d_receive_frame_internal(AVCodecContext *c, Dav1dPicture *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkt->size) {
|
if (pkt->size) {
|
||||||
OpaqueData *od = NULL;
|
|
||||||
|
|
||||||
res = dav1d_data_wrap(data, pkt->data, pkt->size,
|
res = dav1d_data_wrap(data, pkt->data, pkt->size,
|
||||||
libdav1d_data_free, pkt->buf);
|
libdav1d_data_free, pkt->buf);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -351,21 +345,9 @@ static int libdav1d_receive_frame_internal(AVCodecContext *c, Dav1dPicture *p)
|
||||||
|
|
||||||
pkt->buf = NULL;
|
pkt->buf = NULL;
|
||||||
|
|
||||||
if (pkt->opaque && (c->flags & AV_CODEC_FLAG_COPY_OPAQUE)) {
|
|
||||||
od = av_mallocz(sizeof(*od));
|
|
||||||
if (!od) {
|
|
||||||
av_packet_free(&pkt);
|
|
||||||
dav1d_data_unref(data);
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
}
|
|
||||||
od->pkt_orig_opaque = pkt->opaque;
|
|
||||||
}
|
|
||||||
pkt->opaque = od;
|
|
||||||
|
|
||||||
res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt,
|
res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt,
|
||||||
libdav1d_user_data_free, pkt);
|
libdav1d_user_data_free, pkt);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
av_free(pkt->opaque);
|
|
||||||
av_packet_free(&pkt);
|
av_packet_free(&pkt);
|
||||||
dav1d_data_unref(data);
|
dav1d_data_unref(data);
|
||||||
return res;
|
return res;
|
||||||
|
@ -404,7 +386,6 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
Libdav1dContext *dav1d = c->priv_data;
|
Libdav1dContext *dav1d = c->priv_data;
|
||||||
Dav1dPicture pic = { 0 }, *p = &pic;
|
Dav1dPicture pic = { 0 }, *p = &pic;
|
||||||
AVPacket *pkt;
|
AVPacket *pkt;
|
||||||
OpaqueData *od = NULL;
|
|
||||||
#if FF_DAV1D_VERSION_AT_LEAST(5,1)
|
#if FF_DAV1D_VERSION_AT_LEAST(5,1)
|
||||||
enum Dav1dEventFlags event_flags = 0;
|
enum Dav1dEventFlags event_flags = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -459,16 +440,9 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
ff_set_sar(c, frame->sample_aspect_ratio);
|
ff_set_sar(c, frame->sample_aspect_ratio);
|
||||||
|
|
||||||
pkt = (AVPacket *)p->m.user_data.data;
|
pkt = (AVPacket *)p->m.user_data.data;
|
||||||
od = pkt->opaque;
|
|
||||||
|
|
||||||
// restore the original user opaque value for
|
|
||||||
// ff_decode_frame_props_from_pkt()
|
|
||||||
pkt->opaque = od ? od->pkt_orig_opaque : NULL;
|
|
||||||
av_freep(&od);
|
|
||||||
|
|
||||||
// match timestamps and packet size
|
// match timestamps and packet size
|
||||||
res = ff_decode_frame_props_from_pkt(c, frame, pkt);
|
res = ff_decode_frame_props_from_pkt(c, frame, pkt);
|
||||||
pkt->opaque = NULL;
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
@ -542,7 +516,7 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
|
|
||||||
provider_code = bytestream2_get_be16(&gb);
|
provider_code = bytestream2_get_be16(&gb);
|
||||||
switch (provider_code) {
|
switch (provider_code) {
|
||||||
case 0x31: { // atsc_provider_code
|
case ITU_T_T35_PROVIDER_CODE_ATSC: {
|
||||||
uint32_t user_identifier = bytestream2_get_be32(&gb);
|
uint32_t user_identifier = bytestream2_get_be32(&gb);
|
||||||
switch (user_identifier) {
|
switch (user_identifier) {
|
||||||
case MKBETAG('G', 'A', '9', '4'): { // closed captions
|
case MKBETAG('G', 'A', '9', '4'): { // closed captions
|
||||||
|
@ -566,12 +540,12 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x3C: { // smpte_provider_code
|
case ITU_T_T35_PROVIDER_CODE_SMTPE: {
|
||||||
AVDynamicHDRPlus *hdrplus;
|
AVDynamicHDRPlus *hdrplus;
|
||||||
int provider_oriented_code = bytestream2_get_be16(&gb);
|
int provider_oriented_code = bytestream2_get_be16(&gb);
|
||||||
int application_identifier = bytestream2_get_byte(&gb);
|
int application_identifier = bytestream2_get_byte(&gb);
|
||||||
|
|
||||||
if (itut_t35->country_code != 0xB5 ||
|
if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||
|
||||||
provider_oriented_code != 1 || application_identifier != 4)
|
provider_oriented_code != 1 || application_identifier != 4)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -587,9 +561,10 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x3B: { // dolby_provider_code
|
case ITU_T_T35_PROVIDER_CODE_DOLBY: {
|
||||||
int provider_oriented_code = bytestream2_get_be32(&gb);
|
int provider_oriented_code = bytestream2_get_be32(&gb);
|
||||||
if (itut_t35->country_code != 0xB5 || provider_oriented_code != 0x800)
|
if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||
|
||||||
|
provider_oriented_code != 0x800)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer);
|
res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer);
|
||||||
|
@ -613,6 +588,8 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
if (p->frame_hdr->film_grain.present && (!dav1d->apply_grain ||
|
if (p->frame_hdr->film_grain.present && (!dav1d->apply_grain ||
|
||||||
(c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))) {
|
(c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))) {
|
||||||
AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
|
AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
|
||||||
|
const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(frame->format);
|
||||||
|
av_assert0(pixdesc);
|
||||||
if (!fgp) {
|
if (!fgp) {
|
||||||
res = AVERROR(ENOMEM);
|
res = AVERROR(ENOMEM);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -620,6 +597,14 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
|
||||||
|
|
||||||
fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
|
fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
|
||||||
fgp->seed = p->frame_hdr->film_grain.data.seed;
|
fgp->seed = p->frame_hdr->film_grain.data.seed;
|
||||||
|
fgp->width = frame->width;
|
||||||
|
fgp->height = frame->height;
|
||||||
|
fgp->color_range = frame->color_range;
|
||||||
|
fgp->color_primaries = frame->color_primaries;
|
||||||
|
fgp->color_trc = frame->color_trc;
|
||||||
|
fgp->color_space = frame->colorspace;
|
||||||
|
fgp->subsampling_x = pixdesc->log2_chroma_w;
|
||||||
|
fgp->subsampling_y = pixdesc->log2_chroma_h;
|
||||||
fgp->codec.aom.num_y_points = p->frame_hdr->film_grain.data.num_y_points;
|
fgp->codec.aom.num_y_points = p->frame_hdr->film_grain.data.num_y_points;
|
||||||
fgp->codec.aom.chroma_scaling_from_luma = p->frame_hdr->film_grain.data.chroma_scaling_from_luma;
|
fgp->codec.aom.chroma_scaling_from_luma = p->frame_hdr->film_grain.data.chroma_scaling_from_luma;
|
||||||
fgp->codec.aom.scaling_shift = p->frame_hdr->film_grain.data.scaling_shift;
|
fgp->codec.aom.scaling_shift = p->frame_hdr->film_grain.data.scaling_shift;
|
||||||
|
|
|
@ -472,12 +472,8 @@ static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
|
||||||
|
|
||||||
if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
|
if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
|
||||||
fd->frame_opaque = frame->opaque;
|
fd->frame_opaque = frame->opaque;
|
||||||
ret = av_buffer_replace(&fd->frame_opaque_ref, frame->opaque_ref);
|
fd->frame_opaque_ref = frame->opaque_ref;
|
||||||
if (ret < 0) {
|
frame->opaque_ref = NULL;
|
||||||
frame_data_free(fd);
|
|
||||||
av_frame_unref(frame);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rframe = rav1e_frame_new(ctx->ctx);
|
rframe = rav1e_frame_new(ctx->ctx);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/frame.h"
|
#include "libavutil/frame.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
|
#include "libavutil/intreadwrite.h"
|
||||||
|
#include "libavutil/mastering_display_metadata.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
|
@ -136,6 +138,69 @@ static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_mdcv(struct EbSvtAv1MasteringDisplayInfo *dst,
|
||||||
|
const AVMasteringDisplayMetadata *mdcv)
|
||||||
|
{
|
||||||
|
if (mdcv->has_primaries) {
|
||||||
|
const struct EbSvtAv1ChromaPoints *const points[] = {
|
||||||
|
&dst->r,
|
||||||
|
&dst->g,
|
||||||
|
&dst->b,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
const struct EbSvtAv1ChromaPoints *dst = points[i];
|
||||||
|
const AVRational *src = mdcv->display_primaries[i];
|
||||||
|
|
||||||
|
AV_WB16(&dst->x,
|
||||||
|
av_rescale_q(1, src[0], (AVRational){ 1, (1 << 16) }));
|
||||||
|
AV_WB16(&dst->y,
|
||||||
|
av_rescale_q(1, src[1], (AVRational){ 1, (1 << 16) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
AV_WB16(&dst->white_point.x,
|
||||||
|
av_rescale_q(1, mdcv->white_point[0],
|
||||||
|
(AVRational){ 1, (1 << 16) }));
|
||||||
|
AV_WB16(&dst->white_point.y,
|
||||||
|
av_rescale_q(1, mdcv->white_point[1],
|
||||||
|
(AVRational){ 1, (1 << 16) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdcv->has_luminance) {
|
||||||
|
AV_WB32(&dst->max_luma,
|
||||||
|
av_rescale_q(1, mdcv->max_luminance,
|
||||||
|
(AVRational){ 1, (1 << 8) }));
|
||||||
|
AV_WB32(&dst->min_luma,
|
||||||
|
av_rescale_q(1, mdcv->min_luminance,
|
||||||
|
(AVRational){ 1, (1 << 14) }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_side_data(AVCodecContext *avctx,
|
||||||
|
EbSvtAv1EncConfiguration *param)
|
||||||
|
{
|
||||||
|
const AVFrameSideData *cll_sd =
|
||||||
|
av_frame_side_data_get(avctx->decoded_side_data,
|
||||||
|
avctx->nb_decoded_side_data, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
||||||
|
const AVFrameSideData *mdcv_sd =
|
||||||
|
av_frame_side_data_get(avctx->decoded_side_data,
|
||||||
|
avctx->nb_decoded_side_data,
|
||||||
|
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||||
|
|
||||||
|
if (cll_sd) {
|
||||||
|
const AVContentLightMetadata *cll =
|
||||||
|
(AVContentLightMetadata *)cll_sd->data;
|
||||||
|
|
||||||
|
AV_WB16(¶m->content_light_level.max_cll, cll->MaxCLL);
|
||||||
|
AV_WB16(¶m->content_light_level.max_fall, cll->MaxFALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdcv_sd) {
|
||||||
|
handle_mdcv(¶m->mastering_display,
|
||||||
|
(AVMasteringDisplayMetadata *)mdcv_sd->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int config_enc_params(EbSvtAv1EncConfiguration *param,
|
static int config_enc_params(EbSvtAv1EncConfiguration *param,
|
||||||
AVCodecContext *avctx)
|
AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
|
@ -254,6 +319,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
/* 2 = IDR, closed GOP, 1 = CRA, open GOP */
|
/* 2 = IDR, closed GOP, 1 = CRA, open GOP */
|
||||||
param->intra_refresh_type = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? 2 : 1;
|
param->intra_refresh_type = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? 2 : 1;
|
||||||
|
|
||||||
|
handle_side_data(avctx, param);
|
||||||
|
|
||||||
#if SVT_AV1_CHECK_VERSION(0, 9, 1)
|
#if SVT_AV1_CHECK_VERSION(0, 9, 1)
|
||||||
while ((en = av_dict_get(svt_enc->svtav1_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
|
while ((en = av_dict_get(svt_enc->svtav1_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
|
||||||
EbErrorType ret = svt_av1_enc_parse_parameter(param, en->key, en->value);
|
EbErrorType ret = svt_av1_enc_parse_parameter(param, en->key, en->value);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "libavutil/eval.h"
|
#include "libavutil/eval.h"
|
||||||
#include "libavutil/internal.h"
|
#include "libavutil/internal.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
|
#include "libavutil/mastering_display_metadata.h"
|
||||||
#include "libavutil/mem.h"
|
#include "libavutil/mem.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "libavutil/stereo3d.h"
|
#include "libavutil/stereo3d.h"
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
#include "packet_internal.h"
|
#include "packet_internal.h"
|
||||||
#include "atsc_a53.h"
|
#include "atsc_a53.h"
|
||||||
#include "sei.h"
|
#include "sei.h"
|
||||||
|
#include "golomb.h"
|
||||||
|
|
||||||
#include <x264.h>
|
#include <x264.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
@ -847,12 +849,224 @@ static int convert_pix_fmt(enum AVPixelFormat pix_fmt)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int save_sei(AVCodecContext *avctx, x264_nal_t *nal)
|
||||||
|
{
|
||||||
|
X264Context *x4 = avctx->priv_data;
|
||||||
|
|
||||||
|
av_log(avctx, AV_LOG_INFO, "%s\n", nal->p_payload + 25);
|
||||||
|
x4->sei_size = nal->i_payload;
|
||||||
|
x4->sei = av_malloc(x4->sei_size);
|
||||||
|
if (!x4->sei)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
memcpy(x4->sei, nal->p_payload, nal->i_payload);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_LIBX264_ENCODER
|
||||||
|
static int set_avcc_extradata(AVCodecContext *avctx, x264_nal_t *nal, int nnal)
|
||||||
|
{
|
||||||
|
x264_nal_t *sps_nal = NULL;
|
||||||
|
x264_nal_t *pps_nal = NULL;
|
||||||
|
uint8_t *p, *sps;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* We know it's in the order of SPS/PPS/SEI, but it's not documented in x264 API.
|
||||||
|
* The x264 param i_sps_id implies there is a single pair of SPS/PPS.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < nnal; i++) {
|
||||||
|
switch (nal[i].i_type) {
|
||||||
|
case NAL_SPS:
|
||||||
|
sps_nal = &nal[i];
|
||||||
|
break;
|
||||||
|
case NAL_PPS:
|
||||||
|
pps_nal = &nal[i];
|
||||||
|
break;
|
||||||
|
case NAL_SEI:
|
||||||
|
ret = save_sei(avctx, &nal[i]);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sps_nal || !pps_nal)
|
||||||
|
return AVERROR_EXTERNAL;
|
||||||
|
|
||||||
|
avctx->extradata_size = sps_nal->i_payload + pps_nal->i_payload + 7;
|
||||||
|
avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
if (!avctx->extradata)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
// Now create AVCDecoderConfigurationRecord
|
||||||
|
p = avctx->extradata;
|
||||||
|
// Skip size part
|
||||||
|
sps = sps_nal->p_payload + 4;
|
||||||
|
*p++ = 1; // version
|
||||||
|
*p++ = sps[1]; // AVCProfileIndication
|
||||||
|
*p++ = sps[2]; // profile_compatibility
|
||||||
|
*p++ = sps[3]; // AVCLevelIndication
|
||||||
|
*p++ = 0xFF;
|
||||||
|
*p++ = 0xE0 | 0x01; // 3 bits reserved (111) + 5 bits number of sps
|
||||||
|
memcpy(p, sps_nal->p_payload + 2, sps_nal->i_payload - 2);
|
||||||
|
// Make sps has AV_INPUT_BUFFER_PADDING_SIZE padding, so it can be used
|
||||||
|
// with GetBitContext
|
||||||
|
sps = p + 2;
|
||||||
|
p += sps_nal->i_payload - 2;
|
||||||
|
*p++ = 1;
|
||||||
|
memcpy(p, pps_nal->p_payload + 2, pps_nal->i_payload - 2);
|
||||||
|
p += pps_nal->i_payload - 2;
|
||||||
|
|
||||||
|
if (sps[3] != 66 && sps[3] != 77 && sps[3] != 88) {
|
||||||
|
GetBitContext gbc;
|
||||||
|
int chroma_format_idc;
|
||||||
|
int bit_depth_luma_minus8, bit_depth_chroma_minus8;
|
||||||
|
|
||||||
|
/* It's not possible to have emulation prevention byte before
|
||||||
|
* bit_depth_chroma_minus8 due to the range of sps id, chroma_format_idc
|
||||||
|
* and so on. So we can read directly without need to escape emulation
|
||||||
|
* prevention byte.
|
||||||
|
*
|
||||||
|
* +4 to skip until sps id.
|
||||||
|
*/
|
||||||
|
init_get_bits8(&gbc, sps + 4, sps_nal->i_payload - 4 - 4);
|
||||||
|
// Skip sps id
|
||||||
|
get_ue_golomb_31(&gbc);
|
||||||
|
chroma_format_idc = get_ue_golomb_31(&gbc);
|
||||||
|
if (chroma_format_idc == 3)
|
||||||
|
skip_bits1(&gbc);
|
||||||
|
bit_depth_luma_minus8 = get_ue_golomb_31(&gbc);
|
||||||
|
bit_depth_chroma_minus8 = get_ue_golomb_31(&gbc);
|
||||||
|
|
||||||
|
*p++ = 0xFC | chroma_format_idc;
|
||||||
|
*p++ = 0xF8 | bit_depth_luma_minus8;
|
||||||
|
*p++ = 0xF8 | bit_depth_chroma_minus8;
|
||||||
|
*p++ = 0;
|
||||||
|
}
|
||||||
|
av_assert2(avctx->extradata + avctx->extradata_size >= p);
|
||||||
|
avctx->extradata_size = p - avctx->extradata;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int set_extradata(AVCodecContext *avctx)
|
||||||
|
{
|
||||||
|
X264Context *x4 = avctx->priv_data;
|
||||||
|
x264_nal_t *nal;
|
||||||
|
uint8_t *p;
|
||||||
|
int nnal, s;
|
||||||
|
|
||||||
|
s = x264_encoder_headers(x4->enc, &nal, &nnal);
|
||||||
|
if (s < 0)
|
||||||
|
return AVERROR_EXTERNAL;
|
||||||
|
|
||||||
|
#if CONFIG_LIBX264_ENCODER
|
||||||
|
if (!x4->params.b_annexb)
|
||||||
|
return set_avcc_extradata(avctx, nal, nnal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
avctx->extradata = p = av_mallocz(s + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
if (!p)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
for (int i = 0; i < nnal; i++) {
|
||||||
|
/* Don't put the SEI in extradata. */
|
||||||
|
if (nal[i].i_type == NAL_SEI) {
|
||||||
|
s = save_sei(avctx, &nal[i]);
|
||||||
|
if (s < 0)
|
||||||
|
return s;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(p, nal[i].p_payload, nal[i].i_payload);
|
||||||
|
p += nal[i].i_payload;
|
||||||
|
}
|
||||||
|
avctx->extradata_size = p - avctx->extradata;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define PARSE_X264_OPT(name, var)\
|
#define PARSE_X264_OPT(name, var)\
|
||||||
if (x4->var && x264_param_parse(&x4->params, name, x4->var) < 0) {\
|
if (x4->var && x264_param_parse(&x4->params, name, x4->var) < 0) {\
|
||||||
av_log(avctx, AV_LOG_ERROR, "Error parsing option '%s' with value '%s'.\n", name, x4->var);\
|
av_log(avctx, AV_LOG_ERROR, "Error parsing option '%s' with value '%s'.\n", name, x4->var);\
|
||||||
return AVERROR(EINVAL);\
|
return AVERROR(EINVAL);\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_LIBX264_HDR10
|
||||||
|
static void handle_mdcv(x264_param_t *params,
|
||||||
|
const AVMasteringDisplayMetadata *mdcv)
|
||||||
|
{
|
||||||
|
if (!mdcv->has_primaries && !mdcv->has_luminance)
|
||||||
|
return;
|
||||||
|
|
||||||
|
params->mastering_display.b_mastering_display = 1;
|
||||||
|
|
||||||
|
if (mdcv->has_primaries) {
|
||||||
|
int *const points[][2] = {
|
||||||
|
{
|
||||||
|
¶ms->mastering_display.i_red_x,
|
||||||
|
¶ms->mastering_display.i_red_y
|
||||||
|
},
|
||||||
|
{
|
||||||
|
¶ms->mastering_display.i_green_x,
|
||||||
|
¶ms->mastering_display.i_green_y
|
||||||
|
},
|
||||||
|
{
|
||||||
|
¶ms->mastering_display.i_blue_x,
|
||||||
|
¶ms->mastering_display.i_blue_y
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
const AVRational *src = mdcv->display_primaries[i];
|
||||||
|
int *dst[2] = { points[i][0], points[i][1] };
|
||||||
|
|
||||||
|
*dst[0] = av_rescale_q(1, src[0], (AVRational){ 1, 50000 });
|
||||||
|
*dst[1] = av_rescale_q(1, src[1], (AVRational){ 1, 50000 });
|
||||||
|
}
|
||||||
|
|
||||||
|
params->mastering_display.i_white_x =
|
||||||
|
av_rescale_q(1, mdcv->white_point[0], (AVRational){ 1, 50000 });
|
||||||
|
params->mastering_display.i_white_y =
|
||||||
|
av_rescale_q(1, mdcv->white_point[1], (AVRational){ 1, 50000 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdcv->has_luminance) {
|
||||||
|
params->mastering_display.i_display_max =
|
||||||
|
av_rescale_q(1, mdcv->max_luminance, (AVRational){ 1, 10000 });
|
||||||
|
params->mastering_display.i_display_min =
|
||||||
|
av_rescale_q(1, mdcv->min_luminance, (AVRational){ 1, 10000 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CONFIG_LIBX264_HDR10
|
||||||
|
|
||||||
|
static void handle_side_data(AVCodecContext *avctx, x264_param_t *params)
|
||||||
|
{
|
||||||
|
#if CONFIG_LIBX264_HDR10
|
||||||
|
const AVFrameSideData *cll_sd =
|
||||||
|
av_frame_side_data_get(avctx->decoded_side_data,
|
||||||
|
avctx->nb_decoded_side_data, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
||||||
|
const AVFrameSideData *mdcv_sd =
|
||||||
|
av_frame_side_data_get(avctx->decoded_side_data,
|
||||||
|
avctx->nb_decoded_side_data,
|
||||||
|
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||||
|
|
||||||
|
if (cll_sd) {
|
||||||
|
const AVContentLightMetadata *cll =
|
||||||
|
(AVContentLightMetadata *)cll_sd->data;
|
||||||
|
|
||||||
|
params->content_light_level.i_max_cll = cll->MaxCLL;
|
||||||
|
params->content_light_level.i_max_fall = cll->MaxFALL;
|
||||||
|
|
||||||
|
params->content_light_level.b_cll = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdcv_sd) {
|
||||||
|
handle_mdcv(params, (AVMasteringDisplayMetadata *)mdcv_sd->data);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_LIBX264_HDR10
|
||||||
|
}
|
||||||
|
|
||||||
static av_cold int X264_init(AVCodecContext *avctx)
|
static av_cold int X264_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
X264Context *x4 = avctx->priv_data;
|
X264Context *x4 = avctx->priv_data;
|
||||||
|
@ -1153,6 +1367,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
|
if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
|
||||||
x4->params.vui.i_chroma_loc = avctx->chroma_sample_location - 1;
|
x4->params.vui.i_chroma_loc = avctx->chroma_sample_location - 1;
|
||||||
|
|
||||||
|
handle_side_data(avctx, &x4->params);
|
||||||
|
|
||||||
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
|
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
|
||||||
x4->params.b_repeat_headers = 0;
|
x4->params.b_repeat_headers = 0;
|
||||||
|
|
||||||
|
@ -1215,30 +1431,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
return AVERROR_EXTERNAL;
|
return AVERROR_EXTERNAL;
|
||||||
|
|
||||||
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
|
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
|
||||||
x264_nal_t *nal;
|
ret = set_extradata(avctx);
|
||||||
uint8_t *p;
|
if (ret < 0)
|
||||||
int nnal, s, i;
|
return ret;
|
||||||
|
|
||||||
s = x264_encoder_headers(x4->enc, &nal, &nnal);
|
|
||||||
avctx->extradata = p = av_mallocz(s + AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
if (!p)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
|
|
||||||
for (i = 0; i < nnal; i++) {
|
|
||||||
/* Don't put the SEI in extradata. */
|
|
||||||
if (nal[i].i_type == NAL_SEI) {
|
|
||||||
av_log(avctx, AV_LOG_INFO, "%s\n", nal[i].p_payload+25);
|
|
||||||
x4->sei_size = nal[i].i_payload;
|
|
||||||
x4->sei = av_malloc(x4->sei_size);
|
|
||||||
if (!x4->sei)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
memcpy(x4->sei, nal[i].p_payload, nal[i].i_payload);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
memcpy(p, nal[i].p_payload, nal[i].i_payload);
|
|
||||||
p += nal[i].i_payload;
|
|
||||||
}
|
|
||||||
avctx->extradata_size = p - avctx->extradata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpb_props = ff_encode_add_cpb_side_data(avctx);
|
cpb_props = ff_encode_add_cpb_side_data(avctx);
|
||||||
|
|
|
@ -30,13 +30,12 @@
|
||||||
#include "libavutil/avassert.h"
|
#include "libavutil/avassert.h"
|
||||||
#include "libavutil/buffer.h"
|
#include "libavutil/buffer.h"
|
||||||
#include "libavutil/internal.h"
|
#include "libavutil/internal.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/mastering_display_metadata.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "codec_internal.h"
|
#include "codec_internal.h"
|
||||||
#include "encode.h"
|
#include "encode.h"
|
||||||
#include "internal.h"
|
|
||||||
#include "packet_internal.h"
|
#include "packet_internal.h"
|
||||||
#include "atsc_a53.h"
|
#include "atsc_a53.h"
|
||||||
#include "sei.h"
|
#include "sei.h"
|
||||||
|
@ -176,6 +175,68 @@ static av_cold int libx265_param_parse_int(AVCodecContext *avctx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int handle_mdcv(void *logctx, const x265_api *api,
|
||||||
|
x265_param *params,
|
||||||
|
const AVMasteringDisplayMetadata *mdcv)
|
||||||
|
{
|
||||||
|
char buf[10 /* # of PRId64s */ * 20 /* max strlen for %PRId64 */ + sizeof("G(,)B(,)R(,)WP(,)L(,)")];
|
||||||
|
|
||||||
|
// G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)
|
||||||
|
snprintf(buf, sizeof(buf),
|
||||||
|
"G(%"PRId64",%"PRId64")B(%"PRId64",%"PRId64")R(%"PRId64",%"PRId64")"
|
||||||
|
"WP(%"PRId64",%"PRId64")L(%"PRId64",%"PRId64")",
|
||||||
|
av_rescale_q(1, mdcv->display_primaries[1][0], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->display_primaries[1][1], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->display_primaries[2][0], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->display_primaries[2][1], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->display_primaries[0][0], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->display_primaries[0][1], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->white_point[0], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->white_point[1], (AVRational){ 1, 50000 }),
|
||||||
|
av_rescale_q(1, mdcv->max_luminance, (AVRational){ 1, 10000 }),
|
||||||
|
av_rescale_q(1, mdcv->min_luminance, (AVRational){ 1, 10000 }));
|
||||||
|
|
||||||
|
if (api->param_parse(params, "master-display", buf) ==
|
||||||
|
X265_PARAM_BAD_VALUE) {
|
||||||
|
av_log(logctx, AV_LOG_ERROR,
|
||||||
|
"Invalid value \"%s\" for param \"master-display\".\n",
|
||||||
|
buf);
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_side_data(AVCodecContext *avctx, const x265_api *api,
|
||||||
|
x265_param *params)
|
||||||
|
{
|
||||||
|
const AVFrameSideData *cll_sd =
|
||||||
|
av_frame_side_data_get(avctx->decoded_side_data,
|
||||||
|
avctx->nb_decoded_side_data, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
||||||
|
const AVFrameSideData *mdcv_sd =
|
||||||
|
av_frame_side_data_get(avctx->decoded_side_data,
|
||||||
|
avctx->nb_decoded_side_data,
|
||||||
|
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||||
|
|
||||||
|
if (cll_sd) {
|
||||||
|
const AVContentLightMetadata *cll =
|
||||||
|
(AVContentLightMetadata *)cll_sd->data;
|
||||||
|
|
||||||
|
params->maxCLL = cll->MaxCLL;
|
||||||
|
params->maxFALL = cll->MaxFALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdcv_sd) {
|
||||||
|
int ret = handle_mdcv(
|
||||||
|
avctx, api, params,
|
||||||
|
(AVMasteringDisplayMetadata *)mdcv_sd->data);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static av_cold int libx265_encode_init(AVCodecContext *avctx)
|
static av_cold int libx265_encode_init(AVCodecContext *avctx)
|
||||||
{
|
{
|
||||||
libx265Context *ctx = avctx->priv_data;
|
libx265Context *ctx = avctx->priv_data;
|
||||||
|
@ -336,6 +397,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
return AVERROR_BUG;
|
return AVERROR_BUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = handle_side_data(avctx, ctx->api, ctx->params);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Failed handling side data! (%s)\n",
|
||||||
|
av_err2str(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->crf >= 0) {
|
if (ctx->crf >= 0) {
|
||||||
char crf[6];
|
char crf[6];
|
||||||
|
|
||||||
|
|
|
@ -60,31 +60,33 @@ struct JNIAMediaCodecListFields {
|
||||||
jfieldID level_id;
|
jfieldID level_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define OFFSET(x) offsetof(struct JNIAMediaCodecListFields, x)
|
||||||
static const struct FFJniField jni_amediacodeclist_mapping[] = {
|
static const struct FFJniField jni_amediacodeclist_mapping[] = {
|
||||||
{ "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_list_class), 1 },
|
{ "android/media/MediaCodecList", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_list_class), 1 },
|
||||||
{ "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, init_id), 0 },
|
{ "android/media/MediaCodecList", "<init>", "(I)V", FF_JNI_METHOD, OFFSET(init_id), 0 },
|
||||||
{ "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, find_decoder_for_format_id), 0 },
|
{ "android/media/MediaCodecList", "findDecoderForFormat", "(Landroid/media/MediaFormat;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(find_decoder_for_format_id), 0 },
|
||||||
|
|
||||||
{ "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_count_id), 1 },
|
{ "android/media/MediaCodecList", "getCodecCount", "()I", FF_JNI_STATIC_METHOD, OFFSET(get_codec_count_id), 1 },
|
||||||
{ "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_info_at_id), 1 },
|
{ "android/media/MediaCodecList", "getCodecInfoAt", "(I)Landroid/media/MediaCodecInfo;", FF_JNI_STATIC_METHOD, OFFSET(get_codec_info_at_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, mediacodec_info_class), 1 },
|
{ "android/media/MediaCodecInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_info_class), 1 },
|
||||||
{ "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_name_id), 1 },
|
{ "android/media/MediaCodecInfo", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
|
||||||
{ "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_codec_capabilities_id), 1 },
|
{ "android/media/MediaCodecInfo", "getCapabilitiesForType", "(Ljava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", FF_JNI_METHOD, OFFSET(get_codec_capabilities_id), 1 },
|
||||||
{ "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, get_supported_types_id), 1 },
|
{ "android/media/MediaCodecInfo", "getSupportedTypes", "()[Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_supported_types_id), 1 },
|
||||||
{ "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_encoder_id), 1 },
|
{ "android/media/MediaCodecInfo", "isEncoder", "()Z", FF_JNI_METHOD, OFFSET(is_encoder_id), 1 },
|
||||||
{ "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecListFields, is_software_only_id), 0 },
|
{ "android/media/MediaCodecInfo", "isSoftwareOnly", "()Z", FF_JNI_METHOD, OFFSET(is_software_only_id), 0 },
|
||||||
|
|
||||||
{ "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_capabilities_class), 1 },
|
{ "android/media/MediaCodecInfo$CodecCapabilities", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_capabilities_class), 1 },
|
||||||
{ "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, color_formats_id), 1 },
|
{ "android/media/MediaCodecInfo$CodecCapabilities", "colorFormats", "[I", FF_JNI_FIELD, OFFSET(color_formats_id), 1 },
|
||||||
{ "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_levels_id), 1 },
|
{ "android/media/MediaCodecInfo$CodecCapabilities", "profileLevels", "[Landroid/media/MediaCodecInfo$CodecProfileLevel;", FF_JNI_FIELD, OFFSET(profile_levels_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecListFields, codec_profile_level_class), 1 },
|
{ "android/media/MediaCodecInfo$CodecProfileLevel", NULL, NULL, FF_JNI_CLASS, OFFSET(codec_profile_level_class), 1 },
|
||||||
{ "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, profile_id), 1 },
|
{ "android/media/MediaCodecInfo$CodecProfileLevel", "profile", "I", FF_JNI_FIELD, OFFSET(profile_id), 1 },
|
||||||
{ "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecListFields, level_id), 1 },
|
{ "android/media/MediaCodecInfo$CodecProfileLevel", "level", "I", FF_JNI_FIELD, OFFSET(level_id), 1 },
|
||||||
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
#undef OFFSET
|
||||||
|
|
||||||
struct JNIAMediaFormatFields {
|
struct JNIAMediaFormatFields {
|
||||||
|
|
||||||
|
@ -110,29 +112,31 @@ struct JNIAMediaFormatFields {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define OFFSET(x) offsetof(struct JNIAMediaFormatFields, x)
|
||||||
static const struct FFJniField jni_amediaformat_mapping[] = {
|
static const struct FFJniField jni_amediaformat_mapping[] = {
|
||||||
{ "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaFormatFields, mediaformat_class), 1 },
|
{ "android/media/MediaFormat", NULL, NULL, FF_JNI_CLASS, OFFSET(mediaformat_class), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, init_id), 1 },
|
{ "android/media/MediaFormat", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD,offsetof(struct JNIAMediaFormatFields, contains_key_id), 1 },
|
{ "android/media/MediaFormat", "containsKey", "(Ljava/lang/String;)Z", FF_JNI_METHOD, OFFSET(contains_key_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_integer_id), 1 },
|
{ "android/media/MediaFormat", "getInteger", "(Ljava/lang/String;)I", FF_JNI_METHOD, OFFSET(get_integer_id), 1 },
|
||||||
{ "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_long_id), 1 },
|
{ "android/media/MediaFormat", "getLong", "(Ljava/lang/String;)J", FF_JNI_METHOD, OFFSET(get_long_id), 1 },
|
||||||
{ "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_float_id), 1 },
|
{ "android/media/MediaFormat", "getFloat", "(Ljava/lang/String;)F", FF_JNI_METHOD, OFFSET(get_float_id), 1 },
|
||||||
{ "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_bytebuffer_id), 1 },
|
{ "android/media/MediaFormat", "getByteBuffer", "(Ljava/lang/String;)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_bytebuffer_id), 1 },
|
||||||
{ "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, get_string_id), 1 },
|
{ "android/media/MediaFormat", "getString", "(Ljava/lang/String;)Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_string_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_integer_id), 1 },
|
{ "android/media/MediaFormat", "setInteger", "(Ljava/lang/String;I)V", FF_JNI_METHOD, OFFSET(set_integer_id), 1 },
|
||||||
{ "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_long_id), 1 },
|
{ "android/media/MediaFormat", "setLong", "(Ljava/lang/String;J)V", FF_JNI_METHOD, OFFSET(set_long_id), 1 },
|
||||||
{ "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_float_id), 1 },
|
{ "android/media/MediaFormat", "setFloat", "(Ljava/lang/String;F)V", FF_JNI_METHOD, OFFSET(set_float_id), 1 },
|
||||||
{ "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_bytebuffer_id), 1 },
|
{ "android/media/MediaFormat", "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V", FF_JNI_METHOD, OFFSET(set_bytebuffer_id), 1 },
|
||||||
{ "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, set_string_id), 1 },
|
{ "android/media/MediaFormat", "setString", "(Ljava/lang/String;Ljava/lang/String;)V", FF_JNI_METHOD, OFFSET(set_string_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaFormatFields, to_string_id), 1 },
|
{ "android/media/MediaFormat", "toString", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(to_string_id), 1 },
|
||||||
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
#undef OFFSET
|
||||||
|
|
||||||
static const AVClass amediaformat_class = {
|
static const AVClass amediaformat_class = {
|
||||||
.class_name = "amediaformat",
|
.class_name = "amediaformat",
|
||||||
|
@ -202,57 +206,59 @@ struct JNIAMediaCodecFields {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define OFFSET(x) offsetof(struct JNIAMediaCodecFields, x)
|
||||||
static const struct FFJniField jni_amediacodec_mapping[] = {
|
static const struct FFJniField jni_amediacodec_mapping[] = {
|
||||||
{ "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediacodec_class), 1 },
|
{ "android/media/MediaCodec", NULL, NULL, FF_JNI_CLASS, OFFSET(mediacodec_class), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_try_again_later_id), 1 },
|
{ "android/media/MediaCodec", "INFO_TRY_AGAIN_LATER", "I", FF_JNI_STATIC_FIELD, OFFSET(info_try_again_later_id), 1 },
|
||||||
{ "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_buffers_changed_id), 1 },
|
{ "android/media/MediaCodec", "INFO_OUTPUT_BUFFERS_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_buffers_changed_id), 1 },
|
||||||
{ "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, info_output_format_changed_id), 1 },
|
{ "android/media/MediaCodec", "INFO_OUTPUT_FORMAT_CHANGED", "I", FF_JNI_STATIC_FIELD, OFFSET(info_output_format_changed_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_codec_config_id), 1 },
|
{ "android/media/MediaCodec", "BUFFER_FLAG_CODEC_CONFIG", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_codec_config_id), 1 },
|
||||||
{ "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_end_of_stream_id), 1 },
|
{ "android/media/MediaCodec", "BUFFER_FLAG_END_OF_STREAM", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_end_of_stream_id), 1 },
|
||||||
{ "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, buffer_flag_key_frame_id), 0 },
|
{ "android/media/MediaCodec", "BUFFER_FLAG_KEY_FRAME", "I", FF_JNI_STATIC_FIELD, OFFSET(buffer_flag_key_frame_id), 0 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, offsetof(struct JNIAMediaCodecFields, configure_flag_encode_id), 1 },
|
{ "android/media/MediaCodec", "CONFIGURE_FLAG_ENCODE", "I", FF_JNI_STATIC_FIELD, OFFSET(configure_flag_encode_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_by_codec_name_id), 1 },
|
{ "android/media/MediaCodec", "createByCodecName", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_by_codec_name_id), 1 },
|
||||||
{ "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_decoder_by_type_id), 1 },
|
{ "android/media/MediaCodec", "createDecoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_decoder_by_type_id), 1 },
|
||||||
{ "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, offsetof(struct JNIAMediaCodecFields, create_encoder_by_type_id), 1 },
|
{ "android/media/MediaCodec", "createEncoderByType", "(Ljava/lang/String;)Landroid/media/MediaCodec;", FF_JNI_STATIC_METHOD, OFFSET(create_encoder_by_type_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_name_id), 1 },
|
{ "android/media/MediaCodec", "getName", "()Ljava/lang/String;", FF_JNI_METHOD, OFFSET(get_name_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, configure_id), 1 },
|
{ "android/media/MediaCodec", "configure", "(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;I)V", FF_JNI_METHOD, OFFSET(configure_id), 1 },
|
||||||
{ "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, start_id), 1 },
|
{ "android/media/MediaCodec", "start", "()V", FF_JNI_METHOD, OFFSET(start_id), 1 },
|
||||||
{ "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, flush_id), 1 },
|
{ "android/media/MediaCodec", "flush", "()V", FF_JNI_METHOD, OFFSET(flush_id), 1 },
|
||||||
{ "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, stop_id), 1 },
|
{ "android/media/MediaCodec", "stop", "()V", FF_JNI_METHOD, OFFSET(stop_id), 1 },
|
||||||
{ "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_id), 1 },
|
{ "android/media/MediaCodec", "release", "()V", FF_JNI_METHOD, OFFSET(release_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_format_id), 1 },
|
{ "android/media/MediaCodec", "getOutputFormat", "()Landroid/media/MediaFormat;", FF_JNI_METHOD, OFFSET(get_output_format_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_input_buffer_id), 1 },
|
{ "android/media/MediaCodec", "dequeueInputBuffer", "(J)I", FF_JNI_METHOD, OFFSET(dequeue_input_buffer_id), 1 },
|
||||||
{ "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, queue_input_buffer_id), 1 },
|
{ "android/media/MediaCodec", "queueInputBuffer", "(IIIJI)V", FF_JNI_METHOD, OFFSET(queue_input_buffer_id), 1 },
|
||||||
{ "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffer_id), 0 },
|
{ "android/media/MediaCodec", "getInputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffer_id), 0 },
|
||||||
{ "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_input_buffers_id), 1 },
|
{ "android/media/MediaCodec", "getInputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_input_buffers_id), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, dequeue_output_buffer_id), 1 },
|
{ "android/media/MediaCodec", "dequeueOutputBuffer", "(Landroid/media/MediaCodec$BufferInfo;J)I", FF_JNI_METHOD, OFFSET(dequeue_output_buffer_id), 1 },
|
||||||
{ "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffer_id), 0 },
|
{ "android/media/MediaCodec", "getOutputBuffer", "(I)Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffer_id), 0 },
|
||||||
{ "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, get_output_buffers_id), 1 },
|
{ "android/media/MediaCodec", "getOutputBuffers", "()[Ljava/nio/ByteBuffer;", FF_JNI_METHOD, OFFSET(get_output_buffers_id), 1 },
|
||||||
{ "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_id), 1 },
|
{ "android/media/MediaCodec", "releaseOutputBuffer", "(IZ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_id), 1 },
|
||||||
{ "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, release_output_buffer_at_time_id), 0 },
|
{ "android/media/MediaCodec", "releaseOutputBuffer", "(IJ)V", FF_JNI_METHOD, OFFSET(release_output_buffer_at_time_id), 0 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, set_input_surface_id), 0 },
|
{ "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, OFFSET(set_input_surface_id), 0 },
|
||||||
{ "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, signal_end_of_input_stream_id), 0 },
|
{ "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, OFFSET(signal_end_of_input_stream_id), 0 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, offsetof(struct JNIAMediaCodecFields, mediainfo_class), 1 },
|
{ "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediainfo_class), 1 },
|
||||||
|
|
||||||
{ "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, offsetof(struct JNIAMediaCodecFields, init_id), 1 },
|
{ "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
|
||||||
{ "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, flags_id), 1 },
|
{ "android/media/MediaCodec.BufferInfo", "flags", "I", FF_JNI_FIELD, OFFSET(flags_id), 1 },
|
||||||
{ "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, offset_id), 1 },
|
{ "android/media/MediaCodec.BufferInfo", "offset", "I", FF_JNI_FIELD, OFFSET(offset_id), 1 },
|
||||||
{ "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, presentation_time_us_id), 1 },
|
{ "android/media/MediaCodec.BufferInfo", "presentationTimeUs", "J", FF_JNI_FIELD, OFFSET(presentation_time_us_id), 1 },
|
||||||
{ "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, offsetof(struct JNIAMediaCodecFields, size_id), 1 },
|
{ "android/media/MediaCodec.BufferInfo", "size", "I", FF_JNI_FIELD, OFFSET(size_id), 1 },
|
||||||
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
#undef OFFSET
|
||||||
|
|
||||||
static const AVClass amediacodec_class = {
|
static const AVClass amediacodec_class = {
|
||||||
.class_name = "amediacodec",
|
.class_name = "amediacodec",
|
||||||
|
@ -543,10 +549,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codec_name) {
|
(*env)->DeleteLocalRef(env, codec_name);
|
||||||
(*env)->DeleteLocalRef(env, codec_name);
|
codec_name = NULL;
|
||||||
codec_name = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip software decoders */
|
/* Skip software decoders */
|
||||||
if (
|
if (
|
||||||
|
@ -610,10 +614,8 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
|
||||||
|
|
||||||
found_codec = profile == supported_profile;
|
found_codec = profile == supported_profile;
|
||||||
|
|
||||||
if (profile_level) {
|
(*env)->DeleteLocalRef(env, profile_level);
|
||||||
(*env)->DeleteLocalRef(env, profile_level);
|
profile_level = NULL;
|
||||||
profile_level = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_codec) {
|
if (found_codec) {
|
||||||
break;
|
break;
|
||||||
|
@ -621,20 +623,14 @@ char *ff_AMediaCodecList_getCodecNameByType(const char *mime, int profile, int e
|
||||||
}
|
}
|
||||||
|
|
||||||
done_with_type:
|
done_with_type:
|
||||||
if (profile_levels) {
|
(*env)->DeleteLocalRef(env, profile_levels);
|
||||||
(*env)->DeleteLocalRef(env, profile_levels);
|
profile_levels = NULL;
|
||||||
profile_levels = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capabilities) {
|
(*env)->DeleteLocalRef(env, capabilities);
|
||||||
(*env)->DeleteLocalRef(env, capabilities);
|
capabilities = NULL;
|
||||||
capabilities = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type) {
|
(*env)->DeleteLocalRef(env, type);
|
||||||
(*env)->DeleteLocalRef(env, type);
|
type = NULL;
|
||||||
type = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_freep(&supported_type);
|
av_freep(&supported_type);
|
||||||
|
|
||||||
|
@ -644,15 +640,11 @@ done_with_type:
|
||||||
}
|
}
|
||||||
|
|
||||||
done_with_info:
|
done_with_info:
|
||||||
if (info) {
|
(*env)->DeleteLocalRef(env, info);
|
||||||
(*env)->DeleteLocalRef(env, info);
|
info = NULL;
|
||||||
info = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (types) {
|
(*env)->DeleteLocalRef(env, types);
|
||||||
(*env)->DeleteLocalRef(env, types);
|
types = NULL;
|
||||||
types = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found_codec) {
|
if (found_codec) {
|
||||||
break;
|
break;
|
||||||
|
@ -662,33 +654,13 @@ done_with_info:
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (codec_name) {
|
(*env)->DeleteLocalRef(env, codec_name);
|
||||||
(*env)->DeleteLocalRef(env, codec_name);
|
(*env)->DeleteLocalRef(env, info);
|
||||||
}
|
(*env)->DeleteLocalRef(env, type);
|
||||||
|
(*env)->DeleteLocalRef(env, types);
|
||||||
if (info) {
|
(*env)->DeleteLocalRef(env, capabilities);
|
||||||
(*env)->DeleteLocalRef(env, info);
|
(*env)->DeleteLocalRef(env, profile_level);
|
||||||
}
|
(*env)->DeleteLocalRef(env, profile_levels);
|
||||||
|
|
||||||
if (type) {
|
|
||||||
(*env)->DeleteLocalRef(env, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (types) {
|
|
||||||
(*env)->DeleteLocalRef(env, types);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (capabilities) {
|
|
||||||
(*env)->DeleteLocalRef(env, capabilities);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile_level) {
|
|
||||||
(*env)->DeleteLocalRef(env, profile_level);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile_levels) {
|
|
||||||
(*env)->DeleteLocalRef(env, profile_levels);
|
|
||||||
}
|
|
||||||
|
|
||||||
av_freep(&supported_type);
|
av_freep(&supported_type);
|
||||||
|
|
||||||
|
@ -735,9 +707,7 @@ static FFAMediaFormat *mediaformat_jni_new(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (object) {
|
(*env)->DeleteLocalRef(env, object);
|
||||||
(*env)->DeleteLocalRef(env, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!format->object) {
|
if (!format->object) {
|
||||||
ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
|
ff_jni_reset_jfields(env, &format->jfields, jni_amediaformat_mapping, 1, format);
|
||||||
|
@ -822,9 +792,7 @@ static char* mediaformat_jni_toString(FFAMediaFormat* ctx)
|
||||||
|
|
||||||
ret = ff_jni_jstring_to_utf_chars(env, description, format);
|
ret = ff_jni_jstring_to_utf_chars(env, description, format);
|
||||||
fail:
|
fail:
|
||||||
if (description) {
|
(*env)->DeleteLocalRef(env, description);
|
||||||
(*env)->DeleteLocalRef(env, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -861,9 +829,7 @@ static int mediaformat_jni_getInt32(FFAMediaFormat* ctx, const char *name, int32
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -900,9 +866,7 @@ static int mediaformat_jni_getInt64(FFAMediaFormat* ctx, const char *name, int64
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -939,9 +903,7 @@ static int mediaformat_jni_getFloat(FFAMediaFormat* ctx, const char *name, float
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -993,13 +955,8 @@ static int mediaformat_jni_getBuffer(FFAMediaFormat* ctx, const char *name, void
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
(*env)->DeleteLocalRef(env, result);
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
(*env)->DeleteLocalRef(env, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1043,13 +1000,8 @@ static int mediaformat_jni_getString(FFAMediaFormat* ctx, const char *name, cons
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
(*env)->DeleteLocalRef(env, result);
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
(*env)->DeleteLocalRef(env, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1075,9 +1027,7 @@ static void mediaformat_jni_setInt32(FFAMediaFormat* ctx, const char* name, int3
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
|
static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int64_t value)
|
||||||
|
@ -1101,9 +1051,7 @@ static void mediaformat_jni_setInt64(FFAMediaFormat* ctx, const char* name, int6
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, float value)
|
static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, float value)
|
||||||
|
@ -1127,9 +1075,7 @@ static void mediaformat_jni_setFloat(FFAMediaFormat* ctx, const char* name, floa
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, const char* value)
|
static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, const char* value)
|
||||||
|
@ -1159,13 +1105,8 @@ static void mediaformat_jni_setString(FFAMediaFormat* ctx, const char* name, con
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
(*env)->DeleteLocalRef(env, string);
|
||||||
}
|
|
||||||
|
|
||||||
if (string) {
|
|
||||||
(*env)->DeleteLocalRef(env, string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
|
static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, void* data, size_t size)
|
||||||
|
@ -1207,13 +1148,8 @@ static void mediaformat_jni_setBuffer(FFAMediaFormat* ctx, const char* name, voi
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (key) {
|
(*env)->DeleteLocalRef(env, key);
|
||||||
(*env)->DeleteLocalRef(env, key);
|
(*env)->DeleteLocalRef(env, buffer);
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer) {
|
|
||||||
(*env)->DeleteLocalRef(env, buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int codec_init_static_fields(FFAMediaCodecJni *codec)
|
static int codec_init_static_fields(FFAMediaCodecJni *codec)
|
||||||
|
@ -1346,26 +1282,13 @@ static inline FFAMediaCodec *codec_create(int method, const char *arg)
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
fail:
|
fail:
|
||||||
if (jarg) {
|
(*env)->DeleteLocalRef(env, jarg);
|
||||||
(*env)->DeleteLocalRef(env, jarg);
|
(*env)->DeleteLocalRef(env, object);
|
||||||
}
|
(*env)->DeleteLocalRef(env, buffer_info);
|
||||||
|
|
||||||
if (object) {
|
|
||||||
(*env)->DeleteLocalRef(env, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer_info) {
|
|
||||||
(*env)->DeleteLocalRef(env, buffer_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (codec->object) {
|
(*env)->DeleteGlobalRef(env, codec->object);
|
||||||
(*env)->DeleteGlobalRef(env, codec->object);
|
(*env)->DeleteGlobalRef(env, codec->buffer_info);
|
||||||
}
|
|
||||||
|
|
||||||
if (codec->buffer_info) {
|
|
||||||
(*env)->DeleteGlobalRef(env, codec->buffer_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
|
ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);
|
||||||
av_freep(&codec);
|
av_freep(&codec);
|
||||||
|
@ -1686,13 +1609,8 @@ static uint8_t* mediacodec_jni_getInputBuffer(FFAMediaCodec* ctx, size_t idx, si
|
||||||
ret = (*env)->GetDirectBufferAddress(env, buffer);
|
ret = (*env)->GetDirectBufferAddress(env, buffer);
|
||||||
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
|
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||||
fail:
|
fail:
|
||||||
if (buffer) {
|
(*env)->DeleteLocalRef(env, buffer);
|
||||||
(*env)->DeleteLocalRef(env, buffer);
|
(*env)->DeleteLocalRef(env, input_buffers);
|
||||||
}
|
|
||||||
|
|
||||||
if (input_buffers) {
|
|
||||||
(*env)->DeleteLocalRef(env, input_buffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1734,13 +1652,8 @@ static uint8_t* mediacodec_jni_getOutputBuffer(FFAMediaCodec* ctx, size_t idx, s
|
||||||
ret = (*env)->GetDirectBufferAddress(env, buffer);
|
ret = (*env)->GetDirectBufferAddress(env, buffer);
|
||||||
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
|
*out_size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||||
fail:
|
fail:
|
||||||
if (buffer) {
|
(*env)->DeleteLocalRef(env, buffer);
|
||||||
(*env)->DeleteLocalRef(env, buffer);
|
(*env)->DeleteLocalRef(env, output_buffers);
|
||||||
}
|
|
||||||
|
|
||||||
if (output_buffers) {
|
|
||||||
(*env)->DeleteLocalRef(env, output_buffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1762,9 +1675,7 @@ static FFAMediaFormat* mediacodec_jni_getOutputFormat(FFAMediaCodec* ctx)
|
||||||
|
|
||||||
ret = mediaformat_jni_newFromObject(mediaformat);
|
ret = mediaformat_jni_newFromObject(mediaformat);
|
||||||
fail:
|
fail:
|
||||||
if (mediaformat) {
|
(*env)->DeleteLocalRef(env, mediaformat);
|
||||||
(*env)->DeleteLocalRef(env, mediaformat);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,13 @@
|
||||||
|
|
||||||
#define A53_MAX_CC_COUNT 2000
|
#define A53_MAX_CC_COUNT 2000
|
||||||
|
|
||||||
|
enum Mpeg2ClosedCaptionsFormat {
|
||||||
|
CC_FORMAT_AUTO,
|
||||||
|
CC_FORMAT_A53_PART4,
|
||||||
|
CC_FORMAT_SCTE20,
|
||||||
|
CC_FORMAT_DVD
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct Mpeg1Context {
|
typedef struct Mpeg1Context {
|
||||||
MpegEncContext mpeg_enc_ctx;
|
MpegEncContext mpeg_enc_ctx;
|
||||||
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
|
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
|
||||||
|
@ -70,12 +77,14 @@ typedef struct Mpeg1Context {
|
||||||
AVStereo3D stereo3d;
|
AVStereo3D stereo3d;
|
||||||
int has_stereo3d;
|
int has_stereo3d;
|
||||||
AVBufferRef *a53_buf_ref;
|
AVBufferRef *a53_buf_ref;
|
||||||
|
enum Mpeg2ClosedCaptionsFormat cc_format;
|
||||||
uint8_t afd;
|
uint8_t afd;
|
||||||
int has_afd;
|
int has_afd;
|
||||||
int slice_count;
|
int slice_count;
|
||||||
unsigned aspect_ratio_info;
|
unsigned aspect_ratio_info;
|
||||||
AVRational save_aspect;
|
AVRational save_aspect;
|
||||||
int save_width, save_height, save_progressive_seq;
|
int save_width, save_height, save_progressive_seq;
|
||||||
|
enum AVCodecID save_codec_id;
|
||||||
AVRational frame_rate_ext; /* MPEG-2 specific framerate modificator */
|
AVRational frame_rate_ext; /* MPEG-2 specific framerate modificator */
|
||||||
unsigned frame_rate_index;
|
unsigned frame_rate_index;
|
||||||
int sync; /* Did we reach a sync point like a GOP/SEQ/KEYFrame? */
|
int sync; /* Did we reach a sync point like a GOP/SEQ/KEYFrame? */
|
||||||
|
@ -787,9 +796,6 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx)
|
||||||
Mpeg1Context *s = avctx->priv_data;
|
Mpeg1Context *s = avctx->priv_data;
|
||||||
MpegEncContext *s2 = &s->mpeg_enc_ctx;
|
MpegEncContext *s2 = &s->mpeg_enc_ctx;
|
||||||
|
|
||||||
if ( avctx->codec_tag != AV_RL32("VCR2")
|
|
||||||
&& avctx->codec_tag != AV_RL32("BW10"))
|
|
||||||
avctx->coded_width = avctx->coded_height = 0; // do not trust dimensions from input
|
|
||||||
ff_mpv_decode_init(s2, avctx);
|
ff_mpv_decode_init(s2, avctx);
|
||||||
|
|
||||||
ff_mpeg12_init_vlcs();
|
ff_mpeg12_init_vlcs();
|
||||||
|
@ -960,6 +966,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
|
||||||
s1->save_height != s->height ||
|
s1->save_height != s->height ||
|
||||||
av_cmp_q(s1->save_aspect, s->avctx->sample_aspect_ratio) ||
|
av_cmp_q(s1->save_aspect, s->avctx->sample_aspect_ratio) ||
|
||||||
(s1->save_progressive_seq != s->progressive_sequence && FFALIGN(s->height, 16) != FFALIGN(s->height, 32)) ||
|
(s1->save_progressive_seq != s->progressive_sequence && FFALIGN(s->height, 16) != FFALIGN(s->height, 32)) ||
|
||||||
|
s1->save_codec_id != s->codec_id ||
|
||||||
0) {
|
0) {
|
||||||
if (s1->mpeg_enc_ctx_allocated) {
|
if (s1->mpeg_enc_ctx_allocated) {
|
||||||
ff_mpv_common_end(s);
|
ff_mpv_common_end(s);
|
||||||
|
@ -981,6 +988,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
|
||||||
s1->save_width = s->width;
|
s1->save_width = s->width;
|
||||||
s1->save_height = s->height;
|
s1->save_height = s->height;
|
||||||
s1->save_progressive_seq = s->progressive_sequence;
|
s1->save_progressive_seq = s->progressive_sequence;
|
||||||
|
s1->save_codec_id = s->codec_id;
|
||||||
|
|
||||||
/* low_delay may be forced, in this case we will have B-frames
|
/* low_delay may be forced, in this case we will have B-frames
|
||||||
* that behave like P-frames. */
|
* that behave like P-frames. */
|
||||||
|
@ -1013,7 +1021,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
case 1: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
|
case 1: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
|
||||||
case 2:
|
case 2:
|
||||||
case 3: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
|
case 3: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
|
||||||
default: av_assert0(0);
|
|
||||||
}
|
}
|
||||||
} // MPEG-2
|
} // MPEG-2
|
||||||
|
|
||||||
|
@ -1083,6 +1090,7 @@ static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
|
||||||
skip_bits(&s->gb, 1); /* profile and level esc*/
|
skip_bits(&s->gb, 1); /* profile and level esc*/
|
||||||
s->avctx->profile = get_bits(&s->gb, 3);
|
s->avctx->profile = get_bits(&s->gb, 3);
|
||||||
s->avctx->level = get_bits(&s->gb, 4);
|
s->avctx->level = get_bits(&s->gb, 4);
|
||||||
|
s->avctx->progressive_sequence =
|
||||||
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
|
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
|
||||||
s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
|
s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
|
||||||
|
|
||||||
|
@ -1833,6 +1841,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx,
|
||||||
s->height = height;
|
s->height = height;
|
||||||
|
|
||||||
/* We set MPEG-2 parameters so that it emulates MPEG-1. */
|
/* We set MPEG-2 parameters so that it emulates MPEG-1. */
|
||||||
|
s->avctx->progressive_sequence =
|
||||||
s->progressive_sequence = 1;
|
s->progressive_sequence = 1;
|
||||||
s->progressive_frame = 1;
|
s->progressive_frame = 1;
|
||||||
s->picture_structure = PICT_FRAME;
|
s->picture_structure = PICT_FRAME;
|
||||||
|
@ -1886,6 +1895,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
|
||||||
s->chroma_inter_matrix[j] = v;
|
s->chroma_inter_matrix[j] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->avctx->progressive_sequence =
|
||||||
s->progressive_sequence = 1;
|
s->progressive_sequence = 1;
|
||||||
s->progressive_frame = 1;
|
s->progressive_frame = 1;
|
||||||
s->picture_structure = PICT_FRAME;
|
s->picture_structure = PICT_FRAME;
|
||||||
|
@ -1900,15 +1910,31 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
|
||||||
s1->save_width = s->width;
|
s1->save_width = s->width;
|
||||||
s1->save_height = s->height;
|
s1->save_height = s->height;
|
||||||
s1->save_progressive_seq = s->progressive_sequence;
|
s1->save_progressive_seq = s->progressive_sequence;
|
||||||
|
s1->save_codec_id = s->codec_id;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mpeg_set_cc_format(AVCodecContext *avctx, enum Mpeg2ClosedCaptionsFormat format,
|
||||||
|
const char *label)
|
||||||
|
{
|
||||||
|
Mpeg1Context *s1 = avctx->priv_data;
|
||||||
|
|
||||||
|
av_assert2(format != CC_FORMAT_AUTO);
|
||||||
|
|
||||||
|
if (!s1->cc_format) {
|
||||||
|
s1->cc_format = format;
|
||||||
|
|
||||||
|
av_log(avctx, AV_LOG_DEBUG, "CC: first seen substream is %s format\n", label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int mpeg_decode_a53_cc(AVCodecContext *avctx,
|
static int mpeg_decode_a53_cc(AVCodecContext *avctx,
|
||||||
const uint8_t *p, int buf_size)
|
const uint8_t *p, int buf_size)
|
||||||
{
|
{
|
||||||
Mpeg1Context *s1 = avctx->priv_data;
|
Mpeg1Context *s1 = avctx->priv_data;
|
||||||
|
|
||||||
if (buf_size >= 6 &&
|
if ((!s1->cc_format || s1->cc_format == CC_FORMAT_A53_PART4) &&
|
||||||
|
buf_size >= 6 &&
|
||||||
p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
|
p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
|
||||||
p[4] == 3 && (p[5] & 0x40)) {
|
p[4] == 3 && (p[5] & 0x40)) {
|
||||||
/* extract A53 Part 4 CC data */
|
/* extract A53 Part 4 CC data */
|
||||||
|
@ -1927,9 +1953,11 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
|
||||||
memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * UINT64_C(3));
|
memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * UINT64_C(3));
|
||||||
|
|
||||||
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
|
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
|
||||||
|
mpeg_set_cc_format(avctx, CC_FORMAT_A53_PART4, "A/53 Part 4");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else if (buf_size >= 2 &&
|
} else if ((!s1->cc_format || s1->cc_format == CC_FORMAT_SCTE20) &&
|
||||||
|
buf_size >= 2 &&
|
||||||
p[0] == 0x03 && (p[1]&0x7f) == 0x01) {
|
p[0] == 0x03 && (p[1]&0x7f) == 0x01) {
|
||||||
/* extract SCTE-20 CC data */
|
/* extract SCTE-20 CC data */
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
|
@ -1973,10 +2001,13 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
|
||||||
cap += 3;
|
cap += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
|
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
|
||||||
|
mpeg_set_cc_format(avctx, CC_FORMAT_SCTE20, "SCTE-20");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else if (buf_size >= 11 &&
|
} else if ((!s1->cc_format || s1->cc_format == CC_FORMAT_DVD) &&
|
||||||
|
buf_size >= 11 &&
|
||||||
p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
|
p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
|
||||||
/* extract DVD CC data
|
/* extract DVD CC data
|
||||||
*
|
*
|
||||||
|
@ -2033,7 +2064,9 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx,
|
||||||
p += 6;
|
p += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
|
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
|
||||||
|
mpeg_set_cc_format(avctx, CC_FORMAT_DVD, "DVD");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2598,11 +2631,39 @@ const FFCodec ff_mpeg1video_decoder = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define M2V_OFFSET(x) offsetof(Mpeg1Context, x)
|
||||||
|
#define M2V_PARAM AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
|
||||||
|
|
||||||
|
static const AVOption mpeg2video_options[] = {
|
||||||
|
{ "cc_format", "extract a specific Closed Captions format",
|
||||||
|
M2V_OFFSET(cc_format), AV_OPT_TYPE_INT, { .i64 = CC_FORMAT_AUTO },
|
||||||
|
CC_FORMAT_AUTO, CC_FORMAT_DVD, M2V_PARAM, .unit = "cc_format" },
|
||||||
|
|
||||||
|
{ "auto", "pick first seen CC substream", 0, AV_OPT_TYPE_CONST,
|
||||||
|
{ .i64 = CC_FORMAT_AUTO }, .flags = M2V_PARAM, .unit = "cc_format" },
|
||||||
|
{ "a53", "pick A/53 Part 4 CC substream", 0, AV_OPT_TYPE_CONST,
|
||||||
|
{ .i64 = CC_FORMAT_A53_PART4 }, .flags = M2V_PARAM, .unit = "cc_format" },
|
||||||
|
{ "scte20", "pick SCTE-20 CC substream", 0, AV_OPT_TYPE_CONST,
|
||||||
|
{ .i64 = CC_FORMAT_SCTE20 }, .flags = M2V_PARAM, .unit = "cc_format" },
|
||||||
|
{ "dvd", "pick DVD CC substream", 0, AV_OPT_TYPE_CONST,
|
||||||
|
{ .i64 = CC_FORMAT_DVD }, .flags = M2V_PARAM, .unit = "cc_format" },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const AVClass mpeg2video_class = {
|
||||||
|
.class_name = "MPEG-2 video",
|
||||||
|
.item_name = av_default_item_name,
|
||||||
|
.option = mpeg2video_options,
|
||||||
|
.version = LIBAVUTIL_VERSION_INT,
|
||||||
|
.category = AV_CLASS_CATEGORY_DECODER,
|
||||||
|
};
|
||||||
|
|
||||||
const FFCodec ff_mpeg2video_decoder = {
|
const FFCodec ff_mpeg2video_decoder = {
|
||||||
.p.name = "mpeg2video",
|
.p.name = "mpeg2video",
|
||||||
CODEC_LONG_NAME("MPEG-2 video"),
|
CODEC_LONG_NAME("MPEG-2 video"),
|
||||||
.p.type = AVMEDIA_TYPE_VIDEO,
|
.p.type = AVMEDIA_TYPE_VIDEO,
|
||||||
.p.id = AV_CODEC_ID_MPEG2VIDEO,
|
.p.id = AV_CODEC_ID_MPEG2VIDEO,
|
||||||
|
.p.priv_class = &mpeg2video_class,
|
||||||
.priv_data_size = sizeof(Mpeg1Context),
|
.priv_data_size = sizeof(Mpeg1Context),
|
||||||
.init = mpeg_decode_init,
|
.init = mpeg_decode_init,
|
||||||
.close = mpeg_decode_end,
|
.close = mpeg_decode_end,
|
||||||
|
|
|
@ -39,6 +39,7 @@ typedef struct MPEG4AudioConfig {
|
||||||
int channels;
|
int channels;
|
||||||
int ps; ///< -1 implicit, 1 presence
|
int ps; ///< -1 implicit, 1 presence
|
||||||
int frame_length_short;
|
int frame_length_short;
|
||||||
|
int pce;
|
||||||
} MPEG4AudioConfig;
|
} MPEG4AudioConfig;
|
||||||
|
|
||||||
extern const int ff_mpeg4audio_sample_rates[16];
|
extern const int ff_mpeg4audio_sample_rates[16];
|
||||||
|
|
|
@ -344,8 +344,10 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
|
||||||
pic->reference = 3;
|
pic->reference = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alloc_picture(s, pic) < 0)
|
if (alloc_picture(s, pic) < 0) {
|
||||||
|
s->current_picture_ptr = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s->current_picture_ptr = pic;
|
s->current_picture_ptr = pic;
|
||||||
// FIXME use only the vars from current_pic
|
// FIXME use only the vars from current_pic
|
||||||
|
|
|
@ -75,9 +75,15 @@ static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf,
|
||||||
pc->frame_start_found = 4;
|
pc->frame_start_found = 4;
|
||||||
}
|
}
|
||||||
if (state == SEQ_END_CODE) {
|
if (state == SEQ_END_CODE) {
|
||||||
|
int idx = i + 1;
|
||||||
|
/* DVDs won't send the next frame start on still images */
|
||||||
|
/* SEQ_END_CODE will have to stay at the beginning of the next frame */
|
||||||
|
if (pc->frame_start_found && i != 3) {
|
||||||
|
idx = i - 3;
|
||||||
|
}
|
||||||
pc->frame_start_found = 0;
|
pc->frame_start_found = 0;
|
||||||
pc->state = -1;
|
pc->state = -1;
|
||||||
return i + 1;
|
return idx;
|
||||||
}
|
}
|
||||||
if (pc->frame_start_found == 2 && state == SEQ_START_CODE)
|
if (pc->frame_start_found == 2 && state == SEQ_START_CODE)
|
||||||
pc->frame_start_found = 0;
|
pc->frame_start_found = 0;
|
||||||
|
|
|
@ -176,6 +176,8 @@ void avcodec_free_context(AVCodecContext **pavctx)
|
||||||
av_freep(&avctx->inter_matrix);
|
av_freep(&avctx->inter_matrix);
|
||||||
av_freep(&avctx->rc_override);
|
av_freep(&avctx->rc_override);
|
||||||
av_channel_layout_uninit(&avctx->ch_layout);
|
av_channel_layout_uninit(&avctx->ch_layout);
|
||||||
|
av_frame_side_data_free(
|
||||||
|
&avctx->decoded_side_data, &avctx->nb_decoded_side_data);
|
||||||
|
|
||||||
av_freep(pavctx);
|
av_freep(pavctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,9 @@ enum AVPacketSideDataType {
|
||||||
* if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
|
* if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
|
||||||
* s32le width
|
* s32le width
|
||||||
* s32le height
|
* s32le height
|
||||||
|
* if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_ASPECTRATIO)
|
||||||
|
* s32le num
|
||||||
|
* s32le den
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
AV_PKT_DATA_PARAM_CHANGE,
|
AV_PKT_DATA_PARAM_CHANGE,
|
||||||
|
@ -596,8 +599,11 @@ typedef struct AVPacketList {
|
||||||
#define AV_PKT_FLAG_DISPOSABLE 0x0010
|
#define AV_PKT_FLAG_DISPOSABLE 0x0010
|
||||||
|
|
||||||
enum AVSideDataParamChangeFlags {
|
enum AVSideDataParamChangeFlags {
|
||||||
|
AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
|
||||||
|
AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
|
||||||
AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
|
AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
|
||||||
AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
|
AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
|
||||||
|
AV_SIDE_DATA_PARAM_CHANGE_ASPECTRATIO = 0x8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -51,6 +51,7 @@ extern const AVCodecParser ff_gsm_parser;
|
||||||
extern const AVCodecParser ff_h261_parser;
|
extern const AVCodecParser ff_h261_parser;
|
||||||
extern const AVCodecParser ff_h263_parser;
|
extern const AVCodecParser ff_h263_parser;
|
||||||
extern const AVCodecParser ff_h264_parser;
|
extern const AVCodecParser ff_h264_parser;
|
||||||
|
extern const AVCodecParser ff_h264_mvc_parser;
|
||||||
extern const AVCodecParser ff_hevc_parser;
|
extern const AVCodecParser ff_hevc_parser;
|
||||||
extern const AVCodecParser ff_hdr_parser;
|
extern const AVCodecParser ff_hdr_parser;
|
||||||
extern const AVCodecParser ff_ipu_parser;
|
extern const AVCodecParser ff_ipu_parser;
|
||||||
|
|
|
@ -40,6 +40,8 @@ const AVProfile ff_dca_profiles[] = {
|
||||||
{ AV_PROFILE_DTS_ES, "DTS-ES" },
|
{ AV_PROFILE_DTS_ES, "DTS-ES" },
|
||||||
{ AV_PROFILE_DTS_96_24, "DTS 96/24" },
|
{ AV_PROFILE_DTS_96_24, "DTS 96/24" },
|
||||||
{ AV_PROFILE_DTS_HD_HRA, "DTS-HD HRA" },
|
{ AV_PROFILE_DTS_HD_HRA, "DTS-HD HRA" },
|
||||||
|
{ AV_PROFILE_DTS_HD_HRA_X, "DTS-HD HRA + DTS:X" },
|
||||||
|
{ AV_PROFILE_DTS_HD_HRA_X_IMAX, "DTS-HD HRA + DTS:X IMAX"},
|
||||||
{ AV_PROFILE_DTS_HD_MA, "DTS-HD MA" },
|
{ AV_PROFILE_DTS_HD_MA, "DTS-HD MA" },
|
||||||
{ AV_PROFILE_DTS_HD_MA_X, "DTS-HD MA + DTS:X" },
|
{ AV_PROFILE_DTS_HD_MA_X, "DTS-HD MA + DTS:X" },
|
||||||
{ AV_PROFILE_DTS_HD_MA_X_IMAX, "DTS-HD MA + DTS:X IMAX" },
|
{ AV_PROFILE_DTS_HD_MA_X_IMAX, "DTS-HD MA + DTS:X IMAX" },
|
||||||
|
@ -83,6 +85,7 @@ const AVProfile ff_h264_profiles[] = {
|
||||||
{ AV_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" },
|
{ AV_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" },
|
||||||
{ AV_PROFILE_H264_MULTIVIEW_HIGH, "Multiview High" },
|
{ AV_PROFILE_H264_MULTIVIEW_HIGH, "Multiview High" },
|
||||||
{ AV_PROFILE_H264_STEREO_HIGH, "Stereo High" },
|
{ AV_PROFILE_H264_STEREO_HIGH, "Stereo High" },
|
||||||
|
{ FF_PROFILE_H264_MULTIVIEW_HIGH_DEPTH, "Multiview High Depth" },
|
||||||
{ AV_PROFILE_UNKNOWN },
|
{ AV_PROFILE_UNKNOWN },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,27 @@ static av_cold int decode_init(AVCodecContext *avctx)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (avctx->codec_tag) {
|
||||||
|
case MKTAG('a', 'p', 'c', 'h'):
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
||||||
|
break;
|
||||||
|
case MKTAG('a', 'p', 'c', 'n'):
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
||||||
|
break;
|
||||||
|
case MKTAG('a', 'p', 'c', 's'):
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
||||||
|
break;
|
||||||
|
case MKTAG('a', 'p', 'c', 'o'):
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
||||||
|
break;
|
||||||
|
case MKTAG('a', 'p', '4', 'h'):
|
||||||
|
avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
av_log(avctx, AV_LOG_WARNING, "Unknown ProRes FOURCC provided (%08X)\n",
|
||||||
|
avctx->codec_tag);
|
||||||
|
}
|
||||||
|
|
||||||
ff_init_scantable_permutation(idct_permutation,
|
ff_init_scantable_permutation(idct_permutation,
|
||||||
ctx->prodsp.idct_permutation_type);
|
ctx->prodsp.idct_permutation_type);
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
dst->progressive_sequence = src->progressive_sequence;
|
||||||
|
|
||||||
if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
|
if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
|
||||||
(dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
|
(dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
|
||||||
av_buffer_unref(&dst->hw_frames_ctx);
|
av_buffer_unref(&dst->hw_frames_ctx);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/* H.264 slice threading seems to be buggy with more than 16 threads,
|
/* H.264 slice threading seems to be buggy with more than 16 threads,
|
||||||
* limit the number of threads to 16 for automatic detection */
|
* limit the number of threads to 16 for automatic detection */
|
||||||
#define MAX_AUTO_THREADS 16
|
#define MAX_AUTO_THREADS 1
|
||||||
|
|
||||||
int ff_slice_thread_init(AVCodecContext *avctx);
|
int ff_slice_thread_init(AVCodecContext *avctx);
|
||||||
void ff_slice_thread_free(AVCodecContext *avctx);
|
void ff_slice_thread_free(AVCodecContext *avctx);
|
||||||
|
|
|
@ -203,6 +203,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||||
}
|
}
|
||||||
|
|
||||||
avctx->sample_rate = 48000;
|
avctx->sample_rate = 48000;
|
||||||
|
avctx->codec_tag = non_pcm_data_type;
|
||||||
|
|
||||||
*got_frame_ptr = 1;
|
*got_frame_ptr = 1;
|
||||||
|
|
||||||
|
@ -211,7 +212,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, AVFrame *frame,
|
||||||
|
|
||||||
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM
|
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_DECODING_PARAM
|
||||||
static const AVOption s302m_options[] = {
|
static const AVOption s302m_options[] = {
|
||||||
{"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
{"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 2}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
||||||
{"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
{"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
||||||
{"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
{"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
||||||
{"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
{"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, .unit = "non_pcm_mode"},
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define CACHED_BITSTREAM_READER !ARCH_X86_32
|
#define CACHED_BITSTREAM_READER 0 /* cached reader is broken with get_bits_le used below */
|
||||||
#define UNCHECKED_BITSTREAM_READER 1
|
#define UNCHECKED_BITSTREAM_READER 1
|
||||||
|
|
||||||
#include "libavutil/intreadwrite.h"
|
#include "libavutil/intreadwrite.h"
|
||||||
|
|
|
@ -396,6 +396,8 @@ typedef struct VC1Context{
|
||||||
|
|
||||||
int parse_only; ///< Context is used within parser
|
int parse_only; ///< Context is used within parser
|
||||||
int resync_marker; ///< could this stream contain resync markers
|
int resync_marker; ///< could this stream contain resync markers
|
||||||
|
|
||||||
|
int recovered;
|
||||||
} VC1Context;
|
} VC1Context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1045,6 +1045,13 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!v->recovered && !(avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL)) {
|
||||||
|
if (s->pict_type == AV_PICTURE_TYPE_I)
|
||||||
|
v->recovered = 1;
|
||||||
|
else
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
/* skip B-frames if we don't have reference frames */
|
/* skip B-frames if we don't have reference frames */
|
||||||
if (!s->last_picture_ptr && s->pict_type == AV_PICTURE_TYPE_B) {
|
if (!s->last_picture_ptr && s->pict_type == AV_PICTURE_TYPE_B) {
|
||||||
av_log(v->s.avctx, AV_LOG_DEBUG, "Skipping B frame without reference frames\n");
|
av_log(v->s.avctx, AV_LOG_DEBUG, "Skipping B frame without reference frames\n");
|
||||||
|
@ -1381,6 +1388,14 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vc1_decode_flush(AVCodecContext *avctx)
|
||||||
|
{
|
||||||
|
VC1Context *v = avctx->priv_data;
|
||||||
|
|
||||||
|
ff_mpeg_flush(avctx);
|
||||||
|
|
||||||
|
v->recovered = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const FFCodec ff_vc1_decoder = {
|
const FFCodec ff_vc1_decoder = {
|
||||||
.p.name = "vc1",
|
.p.name = "vc1",
|
||||||
|
@ -1391,7 +1406,7 @@ const FFCodec ff_vc1_decoder = {
|
||||||
.init = vc1_decode_init,
|
.init = vc1_decode_init,
|
||||||
.close = ff_vc1_decode_end,
|
.close = ff_vc1_decode_end,
|
||||||
FF_CODEC_DECODE_CB(vc1_decode_frame),
|
FF_CODEC_DECODE_CB(vc1_decode_frame),
|
||||||
.flush = ff_mpeg_flush,
|
.flush = vc1_decode_flush,
|
||||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
|
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
|
||||||
.hw_configs = (const AVCodecHWConfigInternal *const []) {
|
.hw_configs = (const AVCodecHWConfigInternal *const []) {
|
||||||
#if CONFIG_VC1_DXVA2_HWACCEL
|
#if CONFIG_VC1_DXVA2_HWACCEL
|
||||||
|
@ -1430,7 +1445,7 @@ const FFCodec ff_wmv3_decoder = {
|
||||||
.init = vc1_decode_init,
|
.init = vc1_decode_init,
|
||||||
.close = ff_vc1_decode_end,
|
.close = ff_vc1_decode_end,
|
||||||
FF_CODEC_DECODE_CB(vc1_decode_frame),
|
FF_CODEC_DECODE_CB(vc1_decode_frame),
|
||||||
.flush = ff_mpeg_flush,
|
.flush = vc1_decode_flush,
|
||||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
|
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
|
||||||
.hw_configs = (const AVCodecHWConfigInternal *const []) {
|
.hw_configs = (const AVCodecHWConfigInternal *const []) {
|
||||||
#if CONFIG_WMV3_DXVA2_HWACCEL
|
#if CONFIG_WMV3_DXVA2_HWACCEL
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
|
|
||||||
#include "version_major.h"
|
#include "version_major.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MINOR 1
|
#define LIBAVCODEC_VERSION_MINOR 2
|
||||||
#define LIBAVCODEC_VERSION_MICRO 101
|
#define LIBAVCODEC_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
LIBAVCODEC_VERSION_MINOR, \
|
LIBAVCODEC_VERSION_MINOR, \
|
||||||
|
|
|
@ -1341,9 +1341,6 @@ static int decode_tiles(AVCodecContext *avctx,
|
||||||
decode_sb_mem(td, row, col, lflvl_ptr,
|
decode_sb_mem(td, row, col, lflvl_ptr,
|
||||||
yoff2, uvoff2, BL_64X64);
|
yoff2, uvoff2, BL_64X64);
|
||||||
} else {
|
} else {
|
||||||
if (vpx_rac_is_end(td->c)) {
|
|
||||||
return AVERROR_INVALIDDATA;
|
|
||||||
}
|
|
||||||
decode_sb(td, row, col, lflvl_ptr,
|
decode_sb(td, row, col, lflvl_ptr,
|
||||||
yoff2, uvoff2, BL_64X64);
|
yoff2, uvoff2, BL_64X64);
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,10 +250,10 @@ static void set_sps(const HEVCSPS *sps, int sps_idx,
|
||||||
|
|
||||||
*vksps_vui_header = (StdVideoH265HrdParameters) {
|
*vksps_vui_header = (StdVideoH265HrdParameters) {
|
||||||
.flags = (StdVideoH265HrdFlags) {
|
.flags = (StdVideoH265HrdFlags) {
|
||||||
.nal_hrd_parameters_present_flag = sps->hdr.flags.nal_hrd_parameters_present_flag,
|
.nal_hrd_parameters_present_flag = sps->hdr.nal_hrd_parameters_present_flag,
|
||||||
.vcl_hrd_parameters_present_flag = sps->hdr.flags.vcl_hrd_parameters_present_flag,
|
.vcl_hrd_parameters_present_flag = sps->hdr.vcl_hrd_parameters_present_flag,
|
||||||
.sub_pic_hrd_params_present_flag = sps->hdr.flags.sub_pic_hrd_params_present_flag,
|
.sub_pic_hrd_params_present_flag = sps->hdr.sub_pic_hrd_params_present_flag,
|
||||||
.sub_pic_cpb_params_in_pic_timing_sei_flag = sps->hdr.flags.sub_pic_cpb_params_in_pic_timing_sei_flag,
|
.sub_pic_cpb_params_in_pic_timing_sei_flag = sps->hdr.sub_pic_cpb_params_in_pic_timing_sei_flag,
|
||||||
.fixed_pic_rate_general_flag = sps->hdr.flags.fixed_pic_rate_general_flag,
|
.fixed_pic_rate_general_flag = sps->hdr.flags.fixed_pic_rate_general_flag,
|
||||||
.fixed_pic_rate_within_cvs_flag = sps->hdr.flags.fixed_pic_rate_within_cvs_flag,
|
.fixed_pic_rate_within_cvs_flag = sps->hdr.flags.fixed_pic_rate_within_cvs_flag,
|
||||||
.low_delay_hrd_flag = sps->hdr.flags.low_delay_hrd_flag,
|
.low_delay_hrd_flag = sps->hdr.flags.low_delay_hrd_flag,
|
||||||
|
@ -567,10 +567,10 @@ static void set_vps(const HEVCVPS *vps,
|
||||||
|
|
||||||
sls_hdr[i] = (StdVideoH265HrdParameters) {
|
sls_hdr[i] = (StdVideoH265HrdParameters) {
|
||||||
.flags = (StdVideoH265HrdFlags) {
|
.flags = (StdVideoH265HrdFlags) {
|
||||||
.nal_hrd_parameters_present_flag = src->flags.nal_hrd_parameters_present_flag,
|
.nal_hrd_parameters_present_flag = src->nal_hrd_parameters_present_flag,
|
||||||
.vcl_hrd_parameters_present_flag = src->flags.vcl_hrd_parameters_present_flag,
|
.vcl_hrd_parameters_present_flag = src->vcl_hrd_parameters_present_flag,
|
||||||
.sub_pic_hrd_params_present_flag = src->flags.sub_pic_hrd_params_present_flag,
|
.sub_pic_hrd_params_present_flag = src->sub_pic_hrd_params_present_flag,
|
||||||
.sub_pic_cpb_params_in_pic_timing_sei_flag = src->flags.sub_pic_cpb_params_in_pic_timing_sei_flag,
|
.sub_pic_cpb_params_in_pic_timing_sei_flag = src->sub_pic_cpb_params_in_pic_timing_sei_flag,
|
||||||
.fixed_pic_rate_general_flag = src->flags.fixed_pic_rate_general_flag,
|
.fixed_pic_rate_general_flag = src->flags.fixed_pic_rate_general_flag,
|
||||||
.fixed_pic_rate_within_cvs_flag = src->flags.fixed_pic_rate_within_cvs_flag,
|
.fixed_pic_rate_within_cvs_flag = src->flags.fixed_pic_rate_within_cvs_flag,
|
||||||
.low_delay_hrd_flag = src->flags.low_delay_hrd_flag,
|
.low_delay_hrd_flag = src->flags.low_delay_hrd_flag,
|
||||||
|
|
|
@ -96,7 +96,7 @@ static int get_qp_y_pred(const VVCLocalContext *lc)
|
||||||
if (lc->na.cand_up) {
|
if (lc->na.cand_up) {
|
||||||
const int first_qg_in_ctu = !(xQg & ctb_size_mask) && !(yQg & ctb_size_mask);
|
const int first_qg_in_ctu = !(xQg & ctb_size_mask) && !(yQg & ctb_size_mask);
|
||||||
const int qPy_up = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
|
const int qPy_up = fc->tab.qp[LUMA][x_cb + (y_cb - 1) * min_cb_width];
|
||||||
if (first_qg_in_ctu && pps->ctb_to_col_bd[xQg >> ctb_log2_size] == xQg)
|
if (first_qg_in_ctu && pps->ctb_to_col_bd[xQg >> ctb_log2_size] == xQg >> ctb_log2_size)
|
||||||
return qPy_up;
|
return qPy_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1040,8 +1040,7 @@ const FFCodec ff_vvc_decoder = {
|
||||||
.close = vvc_decode_free,
|
.close = vvc_decode_free,
|
||||||
FF_CODEC_DECODE_CB(vvc_decode_frame),
|
FF_CODEC_DECODE_CB(vvc_decode_frame),
|
||||||
.flush = vvc_decode_flush,
|
.flush = vvc_decode_flush,
|
||||||
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS |
|
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
|
||||||
AV_CODEC_CAP_EXPERIMENTAL,
|
|
||||||
.caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_INIT_CLEANUP |
|
.caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_INIT_CLEANUP |
|
||||||
FF_CODEC_CAP_AUTO_THREADS,
|
FF_CODEC_CAP_AUTO_THREADS,
|
||||||
.p.profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
|
.p.profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
|
||||||
|
|
|
@ -173,7 +173,7 @@ static void set_parser_ctx(AVCodecParserContext *s, AVCodecContext *avctx,
|
||||||
h266_sub_width_c[sps->sps_chroma_format_idc];
|
h266_sub_width_c[sps->sps_chroma_format_idc];
|
||||||
s->height = pps->pps_pic_height_in_luma_samples -
|
s->height = pps->pps_pic_height_in_luma_samples -
|
||||||
(pps->pps_conf_win_top_offset + pps->pps_conf_win_bottom_offset) *
|
(pps->pps_conf_win_top_offset + pps->pps_conf_win_bottom_offset) *
|
||||||
h266_sub_height_c[sps->sps_chroma_format_idc];;
|
h266_sub_height_c[sps->sps_chroma_format_idc];
|
||||||
|
|
||||||
avctx->profile = sps->profile_tier_level.general_profile_idc;
|
avctx->profile = sps->profile_tier_level.general_profile_idc;
|
||||||
avctx->level = sps->profile_tier_level.general_level_idc;
|
avctx->level = sps->profile_tier_level.general_level_idc;
|
||||||
|
@ -317,7 +317,7 @@ static int get_pu_info(PuInfo *info, const CodedBitstreamH266Context *h266,
|
||||||
}
|
}
|
||||||
info->pic_type = get_pict_type(pu);
|
info->pic_type = get_pict_type(pu);
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ static int append_au(AVPacket *pkt, const uint8_t *buf, int buf_size)
|
||||||
if ((ret = av_grow_packet(pkt, buf_size)) < 0)
|
if ((ret = av_grow_packet(pkt, buf_size)) < 0)
|
||||||
goto end;
|
goto end;
|
||||||
memcpy(pkt->data + offset, buf, buf_size);
|
memcpy(pkt->data + offset, buf, buf_size);
|
||||||
end:
|
end:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
|
||||||
} else {
|
} else {
|
||||||
ret = 1; //not a completed au
|
ret = 1; //not a completed au
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
ff_cbs_fragment_reset(pu);
|
ff_cbs_fragment_reset(pu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,9 @@ X86ASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_add_res.o \
|
||||||
x86/hevc_mc.o \
|
x86/hevc_mc.o \
|
||||||
x86/h26x/h2656_inter.o \
|
x86/h26x/h2656_inter.o \
|
||||||
x86/hevc_sao.o \
|
x86/hevc_sao.o \
|
||||||
x86/hevc_sao_10bit.o
|
x86/hevc_sao_10bit.o \
|
||||||
|
x86/hevc_idct_intrinsic.o \
|
||||||
|
x86/hevc_intra_intrinsic.o
|
||||||
X86ASM-OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp.o
|
X86ASM-OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp.o
|
||||||
X86ASM-OBJS-$(CONFIG_LSCR_DECODER) += x86/pngdsp.o
|
X86ASM-OBJS-$(CONFIG_LSCR_DECODER) += x86/pngdsp.o
|
||||||
X86ASM-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o
|
X86ASM-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o
|
||||||
|
|
|
@ -0,0 +1,716 @@
|
||||||
|
#include "config.h"
|
||||||
|
#include "libavutil/mem_internal.h"
|
||||||
|
#include "libavutil/avassert.h"
|
||||||
|
#include "libavutil/pixdesc.h"
|
||||||
|
#include "libavcodec/hevc.h"
|
||||||
|
#include "libavcodec/x86/hevcdsp.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC target("sse2")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#include <emmintrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DECLARE_ALIGNED(16, static const int16_t, transform4x4_luma[8][8] )=
|
||||||
|
{
|
||||||
|
{ 29, +84, 29, +84, 29, +84, 29, +84 },
|
||||||
|
{ +74, +55, +74, +55, +74, +55, +74, +55 },
|
||||||
|
{ 55, -29, 55, -29, 55, -29, 55, -29 },
|
||||||
|
{ +74, -84, +74, -84, +74, -84, +74, -84 },
|
||||||
|
{ 74, -74, 74, -74, 74, -74, 74, -74 },
|
||||||
|
{ 0, +74, 0, +74, 0, +74, 0, +74 },
|
||||||
|
{ 84, +55, 84, +55, 84, +55, 84, +55 },
|
||||||
|
{ -74, -29, -74, -29, -74, -29, -74, -29 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_ALIGNED( 16, static const int16_t, transform4x4[4][8] ) = {
|
||||||
|
{ 64, 64, 64, 64, 64, 64, 64, 64 },
|
||||||
|
{ 64, -64, 64, -64, 64, -64, 64, -64 },
|
||||||
|
{ 83, 36, 83, 36, 83, 36, 83, 36 },
|
||||||
|
{ 36, -83, 36, -83, 36, -83, 36, -83 }
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_ALIGNED(16, static const int16_t, transform8x8[12][1][8] )=
|
||||||
|
{
|
||||||
|
{{ 89, 75, 89, 75, 89, 75, 89, 75 }},
|
||||||
|
{{ 50, 18, 50, 18, 50, 18, 50, 18 }},
|
||||||
|
{{ 75, -18, 75, -18, 75, -18, 75, -18 }},
|
||||||
|
{{ -89, -50, -89, -50,-89, -50,-89, -50 }},
|
||||||
|
{{ 50, -89, 50, -89, 50, -89, 50, -89 }},
|
||||||
|
{{ 18, 75, 18, 75, 18, 75, 18, 75 }},
|
||||||
|
{{ 18, -50, 18, -50, 18, -50, 18, -50 }},
|
||||||
|
{{ 75, -89, 75, -89, 75, -89, 75, -89 }},
|
||||||
|
{{ 64, 64, 64, 64, 64, 64, 64, 64 }},
|
||||||
|
{{ 64, -64, 64, -64, 64, -64, 64, -64 }},
|
||||||
|
{{ 83, 36, 83, 36, 83, 36, 83, 36 }},
|
||||||
|
{{ 36, -83, 36, -83, 36, -83, 36, -83 }}
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_ALIGNED(16, static const int16_t, transform16x16_1[4][8][8] )=
|
||||||
|
{
|
||||||
|
{/*1-3*/ /*2-6*/
|
||||||
|
{ 90, 87, 90, 87, 90, 87, 90, 87 },
|
||||||
|
{ 87, 57, 87, 57, 87, 57, 87, 57 },
|
||||||
|
{ 80, 9, 80, 9, 80, 9, 80, 9 },
|
||||||
|
{ 70, -43, 70, -43, 70, -43, 70, -43 },
|
||||||
|
{ 57, -80, 57, -80, 57, -80, 57, -80 },
|
||||||
|
{ 43, -90, 43, -90, 43, -90, 43, -90 },
|
||||||
|
{ 25, -70, 25, -70, 25, -70, 25, -70 },
|
||||||
|
{ 9, -25, 9, -25, 9, -25, 9, -25 },
|
||||||
|
},{ /*5-7*/ /*10-14*/
|
||||||
|
{ 80, 70, 80, 70, 80, 70, 80, 70 },
|
||||||
|
{ 9, -43, 9, -43, 9, -43, 9, -43 },
|
||||||
|
{ -70, -87, -70, -87, -70, -87, -70, -87 },
|
||||||
|
{ -87, 9, -87, 9, -87, 9, -87, 9 },
|
||||||
|
{ -25, 90, -25, 90, -25, 90, -25, 90 },
|
||||||
|
{ 57, 25, 57, 25, 57, 25, 57, 25 },
|
||||||
|
{ 90, -80, 90, -80, 90, -80, 90, -80 },
|
||||||
|
{ 43, -57, 43, -57, 43, -57, 43, -57 },
|
||||||
|
},{ /*9-11*/ /*18-22*/
|
||||||
|
{ 57, 43, 57, 43, 57, 43, 57, 43 },
|
||||||
|
{ -80, -90, -80, -90, -80, -90, -80, -90 },
|
||||||
|
{ -25, 57, -25, 57, -25, 57, -25, 57 },
|
||||||
|
{ 90, 25, 90, 25, 90, 25, 90, 25 },
|
||||||
|
{ -9, -87, -9, -87, -9, -87, -9, -87 },
|
||||||
|
{ -87, 70, -87, 70, -87, 70, -87, 70 },
|
||||||
|
{ 43, 9, 43, 9, 43, 9, 43, 9 },
|
||||||
|
{ 70, -80, 70, -80, 70, -80, 70, -80 },
|
||||||
|
},{/*13-15*/ /* 26-30 */
|
||||||
|
{ 25, 9, 25, 9, 25, 9, 25, 9 },
|
||||||
|
{ -70, -25, -70, -25, -70, -25, -70, -25 },
|
||||||
|
{ 90, 43, 90, 43, 90, 43, 90, 43 },
|
||||||
|
{ -80, -57, -80, -57, -80, -57, -80, -57 },
|
||||||
|
{ 43, 70, 43, 70, 43, 70, 43, 70 },
|
||||||
|
{ 9, -80, 9, -80, 9, -80, 9, -80 },
|
||||||
|
{ -57, 87, -57, 87, -57, 87, -57, 87 },
|
||||||
|
{ 87, -90, 87, -90, 87, -90, 87, -90 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_ALIGNED(16, static const int16_t, transform32x32[8][16][8] )=
|
||||||
|
{
|
||||||
|
{ /* 1-3 */
|
||||||
|
{ 90, 90, 90, 90, 90, 90, 90, 90 },
|
||||||
|
{ 90, 82, 90, 82, 90, 82, 90, 82 },
|
||||||
|
{ 88, 67, 88, 67, 88, 67, 88, 67 },
|
||||||
|
{ 85, 46, 85, 46, 85, 46, 85, 46 },
|
||||||
|
{ 82, 22, 82, 22, 82, 22, 82, 22 },
|
||||||
|
{ 78, -4, 78, -4, 78, -4, 78, -4 },
|
||||||
|
{ 73, -31, 73, -31, 73, -31, 73, -31 },
|
||||||
|
{ 67, -54, 67, -54, 67, -54, 67, -54 },
|
||||||
|
{ 61, -73, 61, -73, 61, -73, 61, -73 },
|
||||||
|
{ 54, -85, 54, -85, 54, -85, 54, -85 },
|
||||||
|
{ 46, -90, 46, -90, 46, -90, 46, -90 },
|
||||||
|
{ 38, -88, 38, -88, 38, -88, 38, -88 },
|
||||||
|
{ 31, -78, 31, -78, 31, -78, 31, -78 },
|
||||||
|
{ 22, -61, 22, -61, 22, -61, 22, -61 },
|
||||||
|
{ 13, -38, 13, -38, 13, -38, 13, -38 },
|
||||||
|
{ 4, -13, 4, -13, 4, -13, 4, -13 },
|
||||||
|
},{/* 5-7 */
|
||||||
|
{ 88, 85, 88, 85, 88, 85, 88, 85 },
|
||||||
|
{ 67, 46, 67, 46, 67, 46, 67, 46 },
|
||||||
|
{ 31, -13, 31, -13, 31, -13, 31, -13 },
|
||||||
|
{ -13, -67, -13, -67, -13, -67, -13, -67 },
|
||||||
|
{ -54, -90, -54, -90, -54, -90, -54, -90 },
|
||||||
|
{ -82, -73, -82, -73, -82, -73, -82, -73 },
|
||||||
|
{ -90, -22, -90, -22, -90, -22, -90, -22 },
|
||||||
|
{ -78, 38, -78, 38, -78, 38, -78, 38 },
|
||||||
|
{ -46, 82, -46, 82, -46, 82, -46, 82 },
|
||||||
|
{ -4, 88, -4, 88, -4, 88, -4, 88 },
|
||||||
|
{ 38, 54, 38, 54, 38, 54, 38, 54 },
|
||||||
|
{ 73, -4, 73, -4, 73, -4, 73, -4 },
|
||||||
|
{ 90, -61, 90, -61, 90, -61, 90, -61 },
|
||||||
|
{ 85, -90, 85, -90, 85, -90, 85, -90 },
|
||||||
|
{ 61, -78, 61, -78, 61, -78, 61, -78 },
|
||||||
|
{ 22, -31, 22, -31, 22, -31, 22, -31 },
|
||||||
|
},{/* 9-11 */
|
||||||
|
{ 82, 78, 82, 78, 82, 78, 82, 78 },
|
||||||
|
{ 22, -4, 22, -4, 22, -4, 22, -4 },
|
||||||
|
{ -54, -82, -54, -82, -54, -82, -54, -82 },
|
||||||
|
{ -90, -73, -90, -73, -90, -73, -90, -73 },
|
||||||
|
{ -61, 13, -61, 13, -61, 13, -61, 13 },
|
||||||
|
{ 13, 85, 13, 85, 13, 85, 13, 85 },
|
||||||
|
{ 78, 67, 78, 67, 78, 67, 78, 67 },
|
||||||
|
{ 85, -22, 85, -22, 85, -22, 85, -22 },
|
||||||
|
{ 31, -88, 31, -88, 31, -88, 31, -88 },
|
||||||
|
{ -46, -61, -46, -61, -46, -61, -46, -61 },
|
||||||
|
{ -90, 31, -90, 31, -90, 31, -90, 31 },
|
||||||
|
{ -67, 90, -67, 90, -67, 90, -67, 90 },
|
||||||
|
{ 4, 54, 4, 54, 4, 54, 4, 54 },
|
||||||
|
{ 73, -38, 73, -38, 73, -38, 73, -38 },
|
||||||
|
{ 88, -90, 88, -90, 88, -90, 88, -90 },
|
||||||
|
{ 38, -46, 38, -46, 38, -46, 38, -46 },
|
||||||
|
},{/* 13-15 */
|
||||||
|
{ 73, 67, 73, 67, 73, 67, 73, 67 },
|
||||||
|
{ -31, -54, -31, -54, -31, -54, -31, -54 },
|
||||||
|
{ -90, -78, -90, -78, -90, -78, -90, -78 },
|
||||||
|
{ -22, 38, -22, 38, -22, 38, -22, 38 },
|
||||||
|
{ 78, 85, 78, 85, 78, 85, 78, 85 },
|
||||||
|
{ 67, -22, 67, -22, 67, -22, 67, -22 },
|
||||||
|
{ -38, -90, -38, -90, -38, -90, -38, -90 },
|
||||||
|
{ -90, 4, -90, 4, -90, 4, -90, 4 },
|
||||||
|
{ -13, 90, -13, 90, -13, 90, -13, 90 },
|
||||||
|
{ 82, 13, 82, 13, 82, 13, 82, 13 },
|
||||||
|
{ 61, -88, 61, -88, 61, -88, 61, -88 },
|
||||||
|
{ -46, -31, -46, -31, -46, -31, -46, -31 },
|
||||||
|
{ -88, 82, -88, 82, -88, 82, -88, 82 },
|
||||||
|
{ -4, 46, -4, 46, -4, 46, -4, 46 },
|
||||||
|
{ 85, -73, 85, -73, 85, -73, 85, -73 },
|
||||||
|
{ 54, -61, 54, -61, 54, -61, 54, -61 },
|
||||||
|
},{/* 17-19 */
|
||||||
|
{ 61, 54, 61, 54, 61, 54, 61, 54 },
|
||||||
|
{ -73, -85, -73, -85, -73, -85, -73, -85 },
|
||||||
|
{ -46, -4, -46, -4, -46, -4, -46, -4 },
|
||||||
|
{ 82, 88, 82, 88, 82, 88, 82, 88 },
|
||||||
|
{ 31, -46, 31, -46, 31, -46, 31, -46 },
|
||||||
|
{ -88, -61, -88, -61, -88, -61, -88, -61 },
|
||||||
|
{ -13, 82, -13, 82, -13, 82, -13, 82 },
|
||||||
|
{ 90, 13, 90, 13, 90, 13, 90, 13 },
|
||||||
|
{ -4, -90, -4, -90, -4, -90, -4, -90 },
|
||||||
|
{ -90, 38, -90, 38, -90, 38, -90, 38 },
|
||||||
|
{ 22, 67, 22, 67, 22, 67, 22, 67 },
|
||||||
|
{ 85, -78, 85, -78, 85, -78, 85, -78 },
|
||||||
|
{ -38, -22, -38, -22, -38, -22, -38, -22 },
|
||||||
|
{ -78, 90, -78, 90, -78, 90, -78, 90 },
|
||||||
|
{ 54, -31, 54, -31, 54, -31, 54, -31 },
|
||||||
|
{ 67, -73, 67, -73, 67, -73, 67, -73 },
|
||||||
|
},{ /* 21-23 */
|
||||||
|
{ 46, 38, 46, 38, 46, 38, 46, 38 },
|
||||||
|
{ -90, -88, -90, -88, -90, -88, -90, -88 },
|
||||||
|
{ 38, 73, 38, 73, 38, 73, 38, 73 },
|
||||||
|
{ 54, -4, 54, -4, 54, -4, 54, -4 },
|
||||||
|
{ -90, -67, -90, -67, -90, -67, -90, -67 },
|
||||||
|
{ 31, 90, 31, 90, 31, 90, 31, 90 },
|
||||||
|
{ 61, -46, 61, -46, 61, -46, 61, -46 },
|
||||||
|
{ -88, -31, -88, -31, -88, -31, -88, -31 },
|
||||||
|
{ 22, 85, 22, 85, 22, 85, 22, 85 },
|
||||||
|
{ 67, -78, 67, -78, 67, -78, 67, -78 },
|
||||||
|
{ -85, 13, -85, 13, -85, 13, -85, 13 },
|
||||||
|
{ 13, 61, 13, 61, 13, 61, 13, 61 },
|
||||||
|
{ 73, -90, 73, -90, 73, -90, 73, -90 },
|
||||||
|
{ -82, 54, -82, 54, -82, 54, -82, 54 },
|
||||||
|
{ 4, 22, 4, 22, 4, 22, 4, 22 },
|
||||||
|
{ 78, -82, 78, -82, 78, -82, 78, -82 },
|
||||||
|
},{ /* 25-27 */
|
||||||
|
{ 31, 22, 31, 22, 31, 22, 31, 22 },
|
||||||
|
{ -78, -61, -78, -61, -78, -61, -78, -61 },
|
||||||
|
{ 90, 85, 90, 85, 90, 85, 90, 85 },
|
||||||
|
{ -61, -90, -61, -90, -61, -90, -61, -90 },
|
||||||
|
{ 4, 73, 4, 73, 4, 73, 4, 73 },
|
||||||
|
{ 54, -38, 54, -38, 54, -38, 54, -38 },
|
||||||
|
{ -88, -4, -88, -4, -88, -4, -88, -4 },
|
||||||
|
{ 82, 46, 82, 46, 82, 46, 82, 46 },
|
||||||
|
{ -38, -78, -38, -78, -38, -78, -38, -78 },
|
||||||
|
{ -22, 90, -22, 90, -22, 90, -22, 90 },
|
||||||
|
{ 73, -82, 73, -82, 73, -82, 73, -82 },
|
||||||
|
{ -90, 54, -90, 54, -90, 54, -90, 54 },
|
||||||
|
{ 67, -13, 67, -13, 67, -13, 67, -13 },
|
||||||
|
{ -13, -31, -13, -31, -13, -31, -13, -31 },
|
||||||
|
{ -46, 67, -46, 67, -46, 67, -46, 67 },
|
||||||
|
{ 85, -88, 85, -88, 85, -88, 85, -88 },
|
||||||
|
},{/* 29-31 */
|
||||||
|
{ 13, 4, 13, 4, 13, 4, 13, 4 },
|
||||||
|
{ -38, -13, -38, -13, -38, -13, -38, -13 },
|
||||||
|
{ 61, 22, 61, 22, 61, 22, 61, 22 },
|
||||||
|
{ -78, -31, -78, -31, -78, -31, -78, -31 },
|
||||||
|
{ 88, 38, 88, 38, 88, 38, 88, 38 },
|
||||||
|
{ -90, -46, -90, -46, -90, -46, -90, -46 },
|
||||||
|
{ 85, 54, 85, 54, 85, 54, 85, 54 },
|
||||||
|
{ -73, -61, -73, -61, -73, -61, -73, -61 },
|
||||||
|
{ 54, 67, 54, 67, 54, 67, 54, 67 },
|
||||||
|
{ -31, -73, -31, -73, -31, -73, -31, -73 },
|
||||||
|
{ 4, 78, 4, 78, 4, 78, 4, 78 },
|
||||||
|
{ 22, -82, 22, -82, 22, -82, 22, -82 },
|
||||||
|
{ -46, 85, -46, 85, -46, 85, -46, 85 },
|
||||||
|
{ 67, -88, 67, -88, 67, -88, 67, -88 },
|
||||||
|
{ -82, 90, -82, 90, -82, 90, -82, 90 },
|
||||||
|
{ 90, -90, 90, -90, 90, -90, 90, -90 },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define shift_1st 7
|
||||||
|
#define add_1st (1 << (shift_1st - 1))
|
||||||
|
|
||||||
|
#define CLIP_PIXEL_MAX_10 0x03FF
|
||||||
|
#define CLIP_PIXEL_MAX_12 0x0FFF
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define INIT_8() \
|
||||||
|
uint8_t *dst = (uint8_t*) _dst; \
|
||||||
|
ptrdiff_t stride = _stride
|
||||||
|
#define INIT_10() \
|
||||||
|
uint16_t *dst = (uint16_t*) _dst; \
|
||||||
|
ptrdiff_t stride = _stride>>1
|
||||||
|
|
||||||
|
#define INIT_12() INIT_10()
|
||||||
|
#define INIT8_12() INIT8_10()
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define LOAD_EMPTY(dst, src)
|
||||||
|
#define LOAD4x4(dst, src) \
|
||||||
|
dst ## 0 = _mm_load_si128((__m128i *) &src[0]); \
|
||||||
|
dst ## 1 = _mm_load_si128((__m128i *) &src[8])
|
||||||
|
#define LOAD4x4_STEP(dst, src, sstep) \
|
||||||
|
tmp0 = _mm_loadl_epi64((__m128i *) &src[0 * sstep]); \
|
||||||
|
tmp1 = _mm_loadl_epi64((__m128i *) &src[1 * sstep]); \
|
||||||
|
tmp2 = _mm_loadl_epi64((__m128i *) &src[2 * sstep]); \
|
||||||
|
tmp3 = _mm_loadl_epi64((__m128i *) &src[3 * sstep]); \
|
||||||
|
dst ## 0 = _mm_unpacklo_epi16(tmp0, tmp2); \
|
||||||
|
dst ## 1 = _mm_unpacklo_epi16(tmp1, tmp3)
|
||||||
|
#define LOAD8x8_E(dst, src, sstep) \
|
||||||
|
dst ## 0 = _mm_load_si128((__m128i *) &src[0 * sstep]); \
|
||||||
|
dst ## 1 = _mm_load_si128((__m128i *) &src[1 * sstep]); \
|
||||||
|
dst ## 2 = _mm_load_si128((__m128i *) &src[2 * sstep]); \
|
||||||
|
dst ## 3 = _mm_load_si128((__m128i *) &src[3 * sstep])
|
||||||
|
#define LOAD8x8_O(dst, src, sstep) \
|
||||||
|
tmp0 = _mm_load_si128((__m128i *) &src[1 * sstep]); \
|
||||||
|
tmp1 = _mm_load_si128((__m128i *) &src[3 * sstep]); \
|
||||||
|
tmp2 = _mm_load_si128((__m128i *) &src[5 * sstep]); \
|
||||||
|
tmp3 = _mm_load_si128((__m128i *) &src[7 * sstep]); \
|
||||||
|
dst ## 0 = _mm_unpacklo_epi16(tmp0, tmp1); \
|
||||||
|
dst ## 1 = _mm_unpackhi_epi16(tmp0, tmp1); \
|
||||||
|
dst ## 2 = _mm_unpacklo_epi16(tmp2, tmp3); \
|
||||||
|
dst ## 3 = _mm_unpackhi_epi16(tmp2, tmp3)
|
||||||
|
#define LOAD16x16_O(dst, src, sstep) \
|
||||||
|
LOAD8x8_O(dst, src, sstep); \
|
||||||
|
tmp0 = _mm_load_si128((__m128i *) &src[ 9 * sstep]); \
|
||||||
|
tmp1 = _mm_load_si128((__m128i *) &src[11 * sstep]); \
|
||||||
|
tmp2 = _mm_load_si128((__m128i *) &src[13 * sstep]); \
|
||||||
|
tmp3 = _mm_load_si128((__m128i *) &src[15 * sstep]); \
|
||||||
|
dst ## 4 = _mm_unpacklo_epi16(tmp0, tmp1); \
|
||||||
|
dst ## 5 = _mm_unpackhi_epi16(tmp0, tmp1); \
|
||||||
|
dst ## 6 = _mm_unpacklo_epi16(tmp2, tmp3); \
|
||||||
|
dst ## 7 = _mm_unpackhi_epi16(tmp2, tmp3)
|
||||||
|
|
||||||
|
#define LOAD_8x32(dst, dst_stride, src0, src1, idx) \
|
||||||
|
src0 = _mm_load_si128((__m128i *) &dst[idx*dst_stride]); \
|
||||||
|
src1 = _mm_load_si128((__m128i *) &dst[idx*dst_stride+4])
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define ASSIGN_EMPTY(dst, dst_stride, src)
|
||||||
|
#define SAVE_8x16(dst, dst_stride, src) \
|
||||||
|
_mm_store_si128((__m128i *) dst, src); \
|
||||||
|
dst += dst_stride
|
||||||
|
#define SAVE_8x32(dst, dst_stride, src0, src1, idx) \
|
||||||
|
_mm_store_si128((__m128i *) &dst[idx*dst_stride] , src0); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[idx*dst_stride+4], src1)
|
||||||
|
|
||||||
|
#define ASSIGN2(dst, dst_stride, src0, src1, assign) \
|
||||||
|
assign(dst, dst_stride, src0); \
|
||||||
|
assign(dst, dst_stride, _mm_srli_si128(src0, 8)); \
|
||||||
|
assign(dst, dst_stride, src1); \
|
||||||
|
assign(dst, dst_stride, _mm_srli_si128(src1, 8))
|
||||||
|
#define ASSIGN4(dst, dst_stride, src0, src1, src2, src3, assign) \
|
||||||
|
assign(dst, dst_stride, src0); \
|
||||||
|
assign(dst, dst_stride, src1); \
|
||||||
|
assign(dst, dst_stride, src2); \
|
||||||
|
assign(dst, dst_stride, src3)
|
||||||
|
#define ASSIGN4_LO(dst, dst_stride, src, assign) \
|
||||||
|
ASSIGN4(dst, dst_stride, src ## 0, src ## 1, src ## 2, src ## 3, assign)
|
||||||
|
#define ASSIGN4_HI(dst, dst_stride, src, assign) \
|
||||||
|
ASSIGN4(dst, dst_stride, src ## 4, src ## 5, src ## 6, src ## 7, assign)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TRANSPOSE4X4_16(dst) \
|
||||||
|
tmp0 = _mm_unpacklo_epi16(dst ## 0, dst ## 1); \
|
||||||
|
tmp1 = _mm_unpackhi_epi16(dst ## 0, dst ## 1); \
|
||||||
|
dst ## 0 = _mm_unpacklo_epi16(tmp0, tmp1); \
|
||||||
|
dst ## 1 = _mm_unpackhi_epi16(tmp0, tmp1)
|
||||||
|
#define TRANSPOSE4X4_16_S(dst, dst_stride, src, assign) \
|
||||||
|
TRANSPOSE4X4_16(src); \
|
||||||
|
ASSIGN2(dst, dst_stride, src ## 0, src ## 1, assign)
|
||||||
|
|
||||||
|
#define TRANSPOSE8X8_16(dst) \
|
||||||
|
tmp0 = _mm_unpacklo_epi16(dst ## 0, dst ## 1); \
|
||||||
|
tmp1 = _mm_unpacklo_epi16(dst ## 2, dst ## 3); \
|
||||||
|
tmp2 = _mm_unpacklo_epi16(dst ## 4, dst ## 5); \
|
||||||
|
tmp3 = _mm_unpacklo_epi16(dst ## 6, dst ## 7); \
|
||||||
|
src0 = _mm_unpacklo_epi32(tmp0, tmp1); \
|
||||||
|
src1 = _mm_unpacklo_epi32(tmp2, tmp3); \
|
||||||
|
src2 = _mm_unpackhi_epi32(tmp0, tmp1); \
|
||||||
|
src3 = _mm_unpackhi_epi32(tmp2, tmp3); \
|
||||||
|
tmp0 = _mm_unpackhi_epi16(dst ## 0, dst ## 1); \
|
||||||
|
tmp1 = _mm_unpackhi_epi16(dst ## 2, dst ## 3); \
|
||||||
|
tmp2 = _mm_unpackhi_epi16(dst ## 4, dst ## 5); \
|
||||||
|
tmp3 = _mm_unpackhi_epi16(dst ## 6, dst ## 7); \
|
||||||
|
dst ## 0 = _mm_unpacklo_epi64(src0 , src1); \
|
||||||
|
dst ## 1 = _mm_unpackhi_epi64(src0 , src1); \
|
||||||
|
dst ## 2 = _mm_unpacklo_epi64(src2 , src3); \
|
||||||
|
dst ## 3 = _mm_unpackhi_epi64(src2 , src3); \
|
||||||
|
src0 = _mm_unpacklo_epi32(tmp0, tmp1); \
|
||||||
|
src1 = _mm_unpacklo_epi32(tmp2, tmp3); \
|
||||||
|
src2 = _mm_unpackhi_epi32(tmp0, tmp1); \
|
||||||
|
src3 = _mm_unpackhi_epi32(tmp2, tmp3); \
|
||||||
|
dst ## 4 = _mm_unpacklo_epi64(src0 , src1); \
|
||||||
|
dst ## 5 = _mm_unpackhi_epi64(src0 , src1); \
|
||||||
|
dst ## 6 = _mm_unpacklo_epi64(src2 , src3); \
|
||||||
|
dst ## 7 = _mm_unpackhi_epi64(src2 , src3)
|
||||||
|
#define TRANSPOSE8x8_16_S(out, sstep_out, src, assign) \
|
||||||
|
TRANSPOSE8X8_16(src); \
|
||||||
|
p_dst = out; \
|
||||||
|
ASSIGN4_LO(p_dst, sstep_out, src, assign); \
|
||||||
|
ASSIGN4_HI(p_dst, sstep_out, src, assign)
|
||||||
|
#define TRANSPOSE8x8_16_LS(out, sstep_out, in, sstep_in, assign) \
|
||||||
|
e0 = _mm_load_si128((__m128i *) &in[0*sstep_in]); \
|
||||||
|
e1 = _mm_load_si128((__m128i *) &in[1*sstep_in]); \
|
||||||
|
e2 = _mm_load_si128((__m128i *) &in[2*sstep_in]); \
|
||||||
|
e3 = _mm_load_si128((__m128i *) &in[3*sstep_in]); \
|
||||||
|
e4 = _mm_load_si128((__m128i *) &in[4*sstep_in]); \
|
||||||
|
e5 = _mm_load_si128((__m128i *) &in[5*sstep_in]); \
|
||||||
|
e6 = _mm_load_si128((__m128i *) &in[6*sstep_in]); \
|
||||||
|
e7 = _mm_load_si128((__m128i *) &in[7*sstep_in]); \
|
||||||
|
TRANSPOSE8x8_16_S(out, sstep_out, e, assign)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TR_COMPUTE_TRANFORM(dst1, dst2, src0, src1, src2, src3, i, j, transform)\
|
||||||
|
tmp1 = _mm_load_si128((__m128i *) transform[i ][j]); \
|
||||||
|
tmp3 = _mm_load_si128((__m128i *) transform[i+1][j]); \
|
||||||
|
tmp0 = _mm_madd_epi16(src0, tmp1); \
|
||||||
|
tmp1 = _mm_madd_epi16(src1, tmp1); \
|
||||||
|
tmp2 = _mm_madd_epi16(src2, tmp3); \
|
||||||
|
tmp3 = _mm_madd_epi16(src3, tmp3); \
|
||||||
|
dst1 = _mm_add_epi32(tmp0, tmp2); \
|
||||||
|
dst2 = _mm_add_epi32(tmp1, tmp3)
|
||||||
|
|
||||||
|
#define SCALE8x8_2x32(dst0, src0, src1) \
|
||||||
|
src0 = _mm_srai_epi32(src0, shift); \
|
||||||
|
src1 = _mm_srai_epi32(src1, shift); \
|
||||||
|
dst0 = _mm_packs_epi32(src0, src1)
|
||||||
|
#define SCALE_4x32(dst0, dst1, src0, src1, src2, src3) \
|
||||||
|
SCALE8x8_2x32(dst0, src0, src1); \
|
||||||
|
SCALE8x8_2x32(dst1, src2, src3)
|
||||||
|
#define SCALE16x16_2x32(dst, dst_stride, src0, src1, j) \
|
||||||
|
e0 = _mm_load_si128((__m128i *) &o16[j*8+0]); \
|
||||||
|
e7 = _mm_load_si128((__m128i *) &o16[j*8+4]); \
|
||||||
|
tmp4 = _mm_add_epi32(src0, e0); \
|
||||||
|
src0 = _mm_sub_epi32(src0, e0); \
|
||||||
|
e0 = _mm_add_epi32(src1, e7); \
|
||||||
|
src1 = _mm_sub_epi32(src1, e7); \
|
||||||
|
SCALE_4x32(e0, e7, tmp4, e0, src0, src1); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*( j)] , e0); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*(dst_stride-1-j)] , e7)
|
||||||
|
|
||||||
|
#define SCALE32x32_2x32(dst, dst_stride, j) \
|
||||||
|
e0 = _mm_load_si128((__m128i *) &e32[j*16+0]); \
|
||||||
|
e1 = _mm_load_si128((__m128i *) &e32[j*16+4]); \
|
||||||
|
e4 = _mm_load_si128((__m128i *) &o32[j*16+0]); \
|
||||||
|
e5 = _mm_load_si128((__m128i *) &o32[j*16+4]); \
|
||||||
|
tmp0 = _mm_add_epi32(e0, e4); \
|
||||||
|
tmp1 = _mm_add_epi32(e1, e5); \
|
||||||
|
tmp2 = _mm_sub_epi32(e1, e5); \
|
||||||
|
tmp3 = _mm_sub_epi32(e0, e4); \
|
||||||
|
SCALE_4x32(tmp0, tmp1, tmp0, tmp1, tmp3, tmp2); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*i+0] , tmp0); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*(dst_stride-1-i)+0] , tmp1)
|
||||||
|
|
||||||
|
#define SAVE16x16_2x32(dst, dst_stride, src0, src1, j) \
|
||||||
|
e0 = _mm_load_si128((__m128i *) &o16[j*8+0]); \
|
||||||
|
e7 = _mm_load_si128((__m128i *) &o16[j*8+4]); \
|
||||||
|
tmp4 = _mm_add_epi32(src0, e0); \
|
||||||
|
src0 = _mm_sub_epi32(src0, e0); \
|
||||||
|
e0 = _mm_add_epi32(src1, e7); \
|
||||||
|
src1 = _mm_sub_epi32(src1, e7); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*( j)] , tmp4); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*( j)+4], e0); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*(dst_stride-1-j)] , src0); \
|
||||||
|
_mm_store_si128((__m128i *) &dst[dst_stride*(dst_stride-1-j)+4], src1)
|
||||||
|
|
||||||
|
|
||||||
|
#define SCALE8x8_2x32_WRAPPER(dst, dst_stride, dst0, src0, src1, idx) \
|
||||||
|
SCALE8x8_2x32(dst0, src0, src1)
|
||||||
|
#define SCALE16x16_2x32_WRAPPER(dst, dst_stride, dst0, src0, src1, idx) \
|
||||||
|
SCALE16x16_2x32(dst, dst_stride, src0, src1, idx)
|
||||||
|
#define SAVE16x16_2x32_WRAPPER(dst, dst_stride, dst0, src0, src1, idx) \
|
||||||
|
SAVE16x16_2x32(dst, dst_stride, src0, src1, idx)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_4x4_luma_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define COMPUTE_LUMA(dst , idx) \
|
||||||
|
tmp0 = _mm_load_si128((__m128i *) (transform4x4_luma[idx ])); \
|
||||||
|
tmp1 = _mm_load_si128((__m128i *) (transform4x4_luma[idx+1])); \
|
||||||
|
tmp0 = _mm_madd_epi16(src0, tmp0); \
|
||||||
|
tmp1 = _mm_madd_epi16(src1, tmp1); \
|
||||||
|
dst = _mm_add_epi32(tmp0, tmp1); \
|
||||||
|
dst = _mm_add_epi32(dst, add); \
|
||||||
|
dst = _mm_srai_epi32(dst, shift)
|
||||||
|
#define COMPUTE_LUMA_ALL() \
|
||||||
|
add = _mm_set1_epi32(1 << (shift - 1)); \
|
||||||
|
src0 = _mm_unpacklo_epi16(tmp0, tmp1); \
|
||||||
|
src1 = _mm_unpackhi_epi16(tmp0, tmp1); \
|
||||||
|
COMPUTE_LUMA(res2 , 0); \
|
||||||
|
COMPUTE_LUMA(res3 , 2); \
|
||||||
|
res0 = _mm_packs_epi32(res2, res3); \
|
||||||
|
COMPUTE_LUMA(res2 , 4); \
|
||||||
|
COMPUTE_LUMA(res3 , 6); \
|
||||||
|
res1 = _mm_packs_epi32(res2, res3)
|
||||||
|
|
||||||
|
#define TRANSFORM_LUMA(D) \
|
||||||
|
void ff_hevc_transform_4x4_luma ## _ ## D ## _sse2(int16_t *_coeffs) { \
|
||||||
|
uint8_t shift = 7; \
|
||||||
|
int16_t *src = _coeffs; \
|
||||||
|
int16_t *coeffs = _coeffs; \
|
||||||
|
__m128i res0, res1, res2, res3; \
|
||||||
|
__m128i tmp0, tmp1, src0, src1, add; \
|
||||||
|
LOAD4x4(tmp, src); \
|
||||||
|
COMPUTE_LUMA_ALL(); \
|
||||||
|
shift = 20 - D; \
|
||||||
|
res2 = _mm_unpacklo_epi16(res0, res1); \
|
||||||
|
res3 = _mm_unpackhi_epi16(res0, res1); \
|
||||||
|
tmp0 = _mm_unpacklo_epi16(res2, res3); \
|
||||||
|
tmp1 = _mm_unpackhi_epi16(res2, res3); \
|
||||||
|
COMPUTE_LUMA_ALL(); \
|
||||||
|
TRANSPOSE4X4_16(res); \
|
||||||
|
_mm_store_si128((__m128i *) coeffs , res0); \
|
||||||
|
_mm_store_si128((__m128i *) (coeffs + 8), res1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANSFORM_LUMA( 8);
|
||||||
|
TRANSFORM_LUMA( 10);
|
||||||
|
TRANSFORM_LUMA( 12);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_4x4_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define COMPUTE4x4(dst0, dst1, dst2, dst3) \
|
||||||
|
tmp0 = _mm_load_si128((__m128i *) transform4x4[0]); \
|
||||||
|
tmp1 = _mm_load_si128((__m128i *) transform4x4[1]); \
|
||||||
|
tmp2 = _mm_load_si128((__m128i *) transform4x4[2]); \
|
||||||
|
tmp3 = _mm_load_si128((__m128i *) transform4x4[3]); \
|
||||||
|
tmp0 = _mm_madd_epi16(e6, tmp0); \
|
||||||
|
tmp1 = _mm_madd_epi16(e6, tmp1); \
|
||||||
|
tmp2 = _mm_madd_epi16(e7, tmp2); \
|
||||||
|
tmp3 = _mm_madd_epi16(e7, tmp3); \
|
||||||
|
e6 = _mm_set1_epi32(add); \
|
||||||
|
tmp0 = _mm_add_epi32(tmp0, e6); \
|
||||||
|
tmp1 = _mm_add_epi32(tmp1, e6); \
|
||||||
|
dst0 = _mm_add_epi32(tmp0, tmp2); \
|
||||||
|
dst1 = _mm_add_epi32(tmp1, tmp3); \
|
||||||
|
dst2 = _mm_sub_epi32(tmp1, tmp3); \
|
||||||
|
dst3 = _mm_sub_epi32(tmp0, tmp2)
|
||||||
|
#define COMPUTE4x4_LO() \
|
||||||
|
COMPUTE4x4(e0, e1, e2, e3)
|
||||||
|
#define COMPUTE4x4_HI(dst) \
|
||||||
|
COMPUTE4x4(e7, e6, e5, e4)
|
||||||
|
|
||||||
|
#define TR_4(dst, dst_stride, in, sstep, load, assign) \
|
||||||
|
load(e, in); \
|
||||||
|
e6 = _mm_unpacklo_epi16(e0, e1); \
|
||||||
|
e7 = _mm_unpackhi_epi16(e0, e1); \
|
||||||
|
COMPUTE4x4_LO(); \
|
||||||
|
SCALE_4x32(e0, e1, e0, e1, e2, e3); \
|
||||||
|
TRANSPOSE4X4_16_S(dst, dst_stride, e, assign) \
|
||||||
|
|
||||||
|
#define TR_4_1( dst, dst_stride, src) TR_4( dst, dst_stride, src, 4, LOAD4x4, ASSIGN_EMPTY)
|
||||||
|
#define TR_4_2( dst, dst_stride, src, D) TR_4( dst, dst_stride, src, 4, LOAD_EMPTY, ASSIGN_EMPTY)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_8x8_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TR_4_set8x4(in, sstep) \
|
||||||
|
LOAD8x8_E(src, in, sstep); \
|
||||||
|
e6 = _mm_unpacklo_epi16(src0, src2); \
|
||||||
|
e7 = _mm_unpacklo_epi16(src1, src3); \
|
||||||
|
COMPUTE4x4_LO(); \
|
||||||
|
e6 = _mm_unpackhi_epi16(src0, src2); \
|
||||||
|
e7 = _mm_unpackhi_epi16(src1, src3); \
|
||||||
|
COMPUTE4x4_HI()
|
||||||
|
|
||||||
|
#define TR_COMPUTE8x8(e0, e1, i) \
|
||||||
|
TR_COMPUTE_TRANFORM(tmp2, tmp3, src0, src1, src2, src3, i, 0, transform8x8);\
|
||||||
|
tmp0 = _mm_add_epi32(e0, tmp2); \
|
||||||
|
tmp1 = _mm_add_epi32(e1, tmp3); \
|
||||||
|
tmp3 = _mm_sub_epi32(e1, tmp3); \
|
||||||
|
tmp2 = _mm_sub_epi32(e0, tmp2)
|
||||||
|
|
||||||
|
#define TR_8(dst, dst_stride, in, sstep, assign) \
|
||||||
|
TR_4_set8x4(in, 2 * sstep); \
|
||||||
|
LOAD8x8_O(src, in, sstep); \
|
||||||
|
TR_COMPUTE8x8(e0, e7, 0); \
|
||||||
|
assign(dst, dst_stride, e0, tmp0, tmp1, 0); \
|
||||||
|
assign(dst, dst_stride, e7, tmp2, tmp3, 7); \
|
||||||
|
TR_COMPUTE8x8(e1, e6, 2); \
|
||||||
|
assign(dst, dst_stride, e1, tmp0, tmp1, 1); \
|
||||||
|
assign(dst, dst_stride, e6, tmp2, tmp3, 6); \
|
||||||
|
TR_COMPUTE8x8(e2, e5, 4); \
|
||||||
|
assign(dst, dst_stride, e2, tmp0, tmp1, 2); \
|
||||||
|
assign(dst, dst_stride, e5, tmp2, tmp3, 5); \
|
||||||
|
TR_COMPUTE8x8(e3, e4, 6); \
|
||||||
|
assign(dst, dst_stride, e3, tmp0, tmp1, 3); \
|
||||||
|
assign(dst, dst_stride, e4, tmp2, tmp3, 4); \
|
||||||
|
|
||||||
|
#define TR_8_1( dst, dst_stride, src) \
|
||||||
|
TR_8( dst, dst_stride, src, 8, SCALE8x8_2x32_WRAPPER); \
|
||||||
|
TRANSPOSE8x8_16_S(dst, dst_stride, e, SAVE_8x16)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_XxX_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define TRANSFORM_4x4(D) \
|
||||||
|
void ff_hevc_transform_4x4_ ## D ## _sse2 (int16_t *_coeffs, int col_limit) { \
|
||||||
|
int16_t *src = _coeffs; \
|
||||||
|
int16_t *coeffs = _coeffs; \
|
||||||
|
int shift = 7; \
|
||||||
|
int add = 1 << (shift - 1); \
|
||||||
|
__m128i tmp0, tmp1, tmp2, tmp3; \
|
||||||
|
__m128i e0, e1, e2, e3, e6, e7; \
|
||||||
|
TR_4_1(p_dst1, 4, src); \
|
||||||
|
shift = 20 - D; \
|
||||||
|
add = 1 << (shift - 1); \
|
||||||
|
TR_4_2(coeffs, 8, tmp, D); \
|
||||||
|
_mm_store_si128((__m128i *) coeffs , e0); \
|
||||||
|
_mm_store_si128((__m128i *) (coeffs + 8), e1); \
|
||||||
|
}
|
||||||
|
#define TRANSFORM_8x8(D) \
|
||||||
|
void ff_hevc_transform_8x8_ ## D ## _sse2 (int16_t *coeffs, int col_limit) { \
|
||||||
|
DECLARE_ALIGNED(16, int16_t, tmp[8*8]); \
|
||||||
|
int16_t *src = coeffs; \
|
||||||
|
int16_t *p_dst1 = tmp; \
|
||||||
|
int16_t *p_dst; \
|
||||||
|
int shift = 7; \
|
||||||
|
int add = 1 << (shift - 1); \
|
||||||
|
__m128i src0, src1, src2, src3; \
|
||||||
|
__m128i tmp0, tmp1, tmp2, tmp3; \
|
||||||
|
__m128i e0, e1, e2, e3, e4, e5, e6, e7; \
|
||||||
|
TR_8_1(p_dst1, 8, src); \
|
||||||
|
shift = 20 - D; \
|
||||||
|
add = 1 << (shift - 1); \
|
||||||
|
TR_8_1(coeffs, 8, tmp); \
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANSFORM_4x4(12)
|
||||||
|
TRANSFORM_8x8(12)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_16x16_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TR_COMPUTE16x16(dst1, dst2,src0, src1, src2, src3, i, j) \
|
||||||
|
TR_COMPUTE_TRANFORM(dst1, dst2,src0, src1, src2, src3, i, j, transform16x16_1)
|
||||||
|
#define TR_COMPUTE16x16_FIRST(j) \
|
||||||
|
TR_COMPUTE16x16(src0, src1, e0, e1, e2, e3, 0, j)
|
||||||
|
#define TR_COMPUTE16x16_NEXT(i, j) \
|
||||||
|
TR_COMPUTE16x16(tmp0, tmp1, e4, e5, e6, e7, i, j); \
|
||||||
|
src0 = _mm_add_epi32(src0, tmp0); \
|
||||||
|
src1 = _mm_add_epi32(src1, tmp1)
|
||||||
|
|
||||||
|
#define TR_16(dst, dst_stride, in, sstep, assign) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
int o16[8*8]; \
|
||||||
|
LOAD16x16_O(e, in, sstep); \
|
||||||
|
for (i = 0; i < 8; i++) { \
|
||||||
|
TR_COMPUTE16x16_FIRST(i); \
|
||||||
|
TR_COMPUTE16x16_NEXT(2, i); \
|
||||||
|
SAVE_8x32(o16, 8, src0, src1, i); \
|
||||||
|
} \
|
||||||
|
TR_8(dst, dst_stride, in, 2 * sstep, assign); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TR_16_1( dst, dst_stride, src) TR_16( dst, dst_stride, src, 16, SCALE16x16_2x32_WRAPPER)
|
||||||
|
#define TR_16_2( dst, dst_stride, src, sstep) TR_16( dst, dst_stride, src, sstep, SAVE16x16_2x32_WRAPPER )
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_32x32_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TR_COMPUTE32x32(dst1, dst2,src0, src1, src2, src3, i, j) \
|
||||||
|
TR_COMPUTE_TRANFORM(dst1, dst2, src0, src1, src2, src3, i, j, transform32x32)
|
||||||
|
#define TR_COMPUTE32x32_FIRST(i, j) \
|
||||||
|
TR_COMPUTE32x32(tmp0, tmp1, e0, e1, e2, e3, i, j); \
|
||||||
|
src0 = _mm_add_epi32(src0, tmp0); \
|
||||||
|
src1 = _mm_add_epi32(src1, tmp1)
|
||||||
|
#define TR_COMPUTE32x32_NEXT(i, j) \
|
||||||
|
TR_COMPUTE32x32(tmp0, tmp1, e4, e5, e6, e7, i, j); \
|
||||||
|
src0 = _mm_add_epi32(src0, tmp0); \
|
||||||
|
src1 = _mm_add_epi32(src1, tmp1)
|
||||||
|
|
||||||
|
#define TR_32(dst, dst_stride, in, sstep) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
DECLARE_ALIGNED(16, int, e32[16*16]); \
|
||||||
|
DECLARE_ALIGNED(16, int, o32[16*16]); \
|
||||||
|
LOAD16x16_O(e, in, sstep); \
|
||||||
|
for (i = 0; i < 16; i++) { \
|
||||||
|
src0 = _mm_setzero_si128(); \
|
||||||
|
src1 = _mm_setzero_si128(); \
|
||||||
|
TR_COMPUTE32x32_FIRST(0, i); \
|
||||||
|
TR_COMPUTE32x32_NEXT(2, i); \
|
||||||
|
SAVE_8x32(o32, 16, src0, src1, i); \
|
||||||
|
} \
|
||||||
|
LOAD16x16_O(e, (&in[16*sstep]), sstep); \
|
||||||
|
for (i = 0; i < 16; i++) { \
|
||||||
|
LOAD_8x32(o32, 16, src0, src1, i); \
|
||||||
|
TR_COMPUTE32x32_FIRST(4, i); \
|
||||||
|
TR_COMPUTE32x32_NEXT(6, i); \
|
||||||
|
SAVE_8x32(o32, 16, src0, src1, i); \
|
||||||
|
} \
|
||||||
|
TR_16_2(e32, 16, in, 2 * sstep); \
|
||||||
|
for (i = 0; i < 16; i++) { \
|
||||||
|
SCALE32x32_2x32(dst, dst_stride, i); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TR_32_1( dst, dst_stride, src) TR_32( dst, dst_stride, src, 32)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ff_hevc_transform_XxX_X_sse2
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TRANSFORM2(H, D) \
|
||||||
|
void ff_hevc_transform_ ## H ## x ## H ## _ ## D ## _sse2 ( \
|
||||||
|
int16_t *coeffs, int col_limit) { \
|
||||||
|
int i, j, k, add; \
|
||||||
|
int shift = 7; \
|
||||||
|
int16_t *src = coeffs; \
|
||||||
|
DECLARE_ALIGNED(16, int16_t, tmp[H*H]); \
|
||||||
|
DECLARE_ALIGNED(16, int16_t, tmp_2[H*H]); \
|
||||||
|
int16_t *p_dst, *p_tra = tmp_2; \
|
||||||
|
__m128i src0, src1, src2, src3; \
|
||||||
|
__m128i tmp0, tmp1, tmp2, tmp3, tmp4; \
|
||||||
|
__m128i e0, e1, e2, e3, e4, e5, e6, e7; \
|
||||||
|
for (k = 0; k < 2; k++) { \
|
||||||
|
add = 1 << (shift - 1); \
|
||||||
|
for (i = 0; i < H; i+=8) { \
|
||||||
|
p_dst = tmp + i; \
|
||||||
|
TR_ ## H ## _1(p_dst, H, src); \
|
||||||
|
src += 8; \
|
||||||
|
for (j = 0; j < H; j+=8) { \
|
||||||
|
TRANSPOSE8x8_16_LS((&p_tra[i*H+j]), H, (&tmp[j*H+i]), H, SAVE_8x16);\
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
src = tmp_2; \
|
||||||
|
p_tra = coeffs; \
|
||||||
|
shift = 20 - D; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !ARCH_X86_64
|
||||||
|
TRANSFORM2(16, 8);
|
||||||
|
TRANSFORM2(16, 10);
|
||||||
|
#endif
|
||||||
|
TRANSFORM2(16, 12);
|
||||||
|
|
||||||
|
#if !ARCH_X86_64
|
||||||
|
TRANSFORM2(32, 8);
|
||||||
|
TRANSFORM2(32, 10);
|
||||||
|
#endif
|
||||||
|
TRANSFORM2(32, 12);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC pop_options
|
||||||
|
#endif
|
|
@ -0,0 +1,922 @@
|
||||||
|
#include "config.h"
|
||||||
|
#include "libavutil/avassert.h"
|
||||||
|
#include "libavutil/pixdesc.h"
|
||||||
|
#include "libavcodec/get_bits.h"
|
||||||
|
#include "libavcodec/hevc.h"
|
||||||
|
#include "libavcodec/x86/hevcpred.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC target("sse4.1")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SSE2
|
||||||
|
#include <emmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSSE3
|
||||||
|
#include <tmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if HAVE_SSE4
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SSE4
|
||||||
|
#define _MM_PACKUS_EPI32 _mm_packus_epi32
|
||||||
|
#else
|
||||||
|
static av_always_inline __m128i _MM_PACKUS_EPI32( __m128i a, __m128i b )
|
||||||
|
{
|
||||||
|
a = _mm_slli_epi32 (a, 16);
|
||||||
|
a = _mm_srai_epi32 (a, 16);
|
||||||
|
b = _mm_slli_epi32 (b, 16);
|
||||||
|
b = _mm_srai_epi32 (b, 16);
|
||||||
|
a = _mm_packs_epi32 (a, b);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if HAVE_SSE4
|
||||||
|
#define PLANAR_INIT_8() \
|
||||||
|
uint8_t *src = (uint8_t*)_src; \
|
||||||
|
const uint8_t *top = (const uint8_t*)_top; \
|
||||||
|
const uint8_t *left = (const uint8_t*)_left
|
||||||
|
#define PLANAR_INIT_10() \
|
||||||
|
uint16_t *src = (uint16_t*)_src; \
|
||||||
|
const uint16_t *top = (const uint16_t*)_top; \
|
||||||
|
const uint16_t *left = (const uint16_t*)_left
|
||||||
|
|
||||||
|
#define PLANAR_COMPUTE(val, shift) \
|
||||||
|
add = _mm_mullo_epi16(_mm_set1_epi16(1+y), l0); \
|
||||||
|
ly1 = _mm_unpacklo_epi16(ly , ly ); \
|
||||||
|
ly1 = _mm_unpacklo_epi32(ly1, ly1); \
|
||||||
|
ly1 = _mm_unpacklo_epi64(ly1, ly1); \
|
||||||
|
c0 = _mm_mullo_epi16(tmp1, ly1); \
|
||||||
|
x0 = _mm_mullo_epi16(_mm_set1_epi16(val - y), tx); \
|
||||||
|
c0 = _mm_add_epi16(c0, c1); \
|
||||||
|
x0 = _mm_add_epi16(x0, c0); \
|
||||||
|
x0 = _mm_add_epi16(x0, add); \
|
||||||
|
c0 = _mm_srli_epi16(x0, shift)
|
||||||
|
|
||||||
|
#define PLANAR_COMPUTE_HI(val, shift) \
|
||||||
|
C0 = _mm_mullo_epi16(tmp2, ly1); \
|
||||||
|
x0 = _mm_mullo_epi16(_mm_set1_epi16(val - y), th); \
|
||||||
|
C0 = _mm_add_epi16(C0, C1); \
|
||||||
|
x0 = _mm_add_epi16(x0, C0); \
|
||||||
|
x0 = _mm_add_epi16(x0, add); \
|
||||||
|
C0 = _mm_srli_epi16(x0, shift)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define PLANAR_LOAD_0_8() \
|
||||||
|
ly = _mm_loadl_epi64((__m128i*) left); \
|
||||||
|
tx = _mm_loadl_epi64((__m128i*) top); \
|
||||||
|
ly = _mm_unpacklo_epi8(ly, _mm_setzero_si128()); \
|
||||||
|
tx = _mm_unpacklo_epi8(tx, _mm_setzero_si128()); \
|
||||||
|
ly = _mm_unpacklo_epi16(ly, ly); \
|
||||||
|
tx = _mm_unpacklo_epi64(tx, tx)
|
||||||
|
#define PLANAR_LOAD_0_10() \
|
||||||
|
ly = _mm_loadl_epi64((__m128i*) left); \
|
||||||
|
tx = _mm_loadl_epi64((__m128i*) top); \
|
||||||
|
ly = _mm_unpacklo_epi16(ly, ly); \
|
||||||
|
tx = _mm_unpacklo_epi64(tx, tx)
|
||||||
|
|
||||||
|
#define PLANAR_COMPUTE_0(dst , v1, v2, v3, v4) \
|
||||||
|
dst = _mm_mullo_epi16(tmp1, ly1); \
|
||||||
|
x0 = _mm_mullo_epi16(_mm_set_epi16(v1,v1,v1,v1,v2,v2,v2,v2), tx); \
|
||||||
|
add = _mm_mullo_epi16(_mm_set_epi16(v3,v3,v3,v3,v4,v4,v4,v4), l0); \
|
||||||
|
dst = _mm_add_epi16(dst, c1); \
|
||||||
|
x0 = _mm_add_epi16(x0, add); \
|
||||||
|
dst = _mm_add_epi16(dst, x0); \
|
||||||
|
dst = _mm_srli_epi16(dst, 3)
|
||||||
|
|
||||||
|
#define PLANAR_STORE_0_8() \
|
||||||
|
c0 = _mm_packus_epi16(c0,C0); \
|
||||||
|
*((uint32_t *) src ) = _mm_cvtsi128_si32(c0 ); \
|
||||||
|
*((uint32_t *)(src + stride)) = _mm_extract_epi32(c0, 1); \
|
||||||
|
*((uint32_t *)(src + 2 * stride)) = _mm_extract_epi32(c0, 2); \
|
||||||
|
*((uint32_t *)(src + 3 * stride)) = _mm_extract_epi32(c0, 3)
|
||||||
|
#define PLANAR_STORE_0_10() \
|
||||||
|
_mm_storel_epi64((__m128i*)(src ), c0); \
|
||||||
|
_mm_storel_epi64((__m128i*)(src + stride), _mm_unpackhi_epi64(c0, c0));\
|
||||||
|
_mm_storel_epi64((__m128i*)(src + 2 * stride), C0); \
|
||||||
|
_mm_storel_epi64((__m128i*)(src + 3 * stride), _mm_unpackhi_epi64(C0, C0))
|
||||||
|
|
||||||
|
#define PRED_PLANAR_0(D) \
|
||||||
|
void pred_planar_0_ ## D ## _sse(uint8_t *_src, const uint8_t *_top, \
|
||||||
|
const uint8_t *_left, ptrdiff_t stride) { \
|
||||||
|
__m128i ly, l0, tx, ly1; \
|
||||||
|
__m128i tmp1, add, x0, c0, c1, C0; \
|
||||||
|
PLANAR_INIT_ ## D(); \
|
||||||
|
tx = _mm_set1_epi16(top[4]); \
|
||||||
|
l0 = _mm_set1_epi16(left[4]); \
|
||||||
|
add = _mm_set1_epi16(4); \
|
||||||
|
tmp1 = _mm_set_epi16(0,1,2,3,0,1,2,3); \
|
||||||
|
c1 = _mm_mullo_epi16(_mm_set_epi16(4,3,2,1,4,3,2,1), tx); \
|
||||||
|
c1 = _mm_add_epi16(c1, add); \
|
||||||
|
PLANAR_LOAD_0_ ##D(); \
|
||||||
|
\
|
||||||
|
ly1 = _mm_unpacklo_epi32(ly, ly); \
|
||||||
|
PLANAR_COMPUTE_0(c0, 2, 3, 2, 1); \
|
||||||
|
ly1 = _mm_unpackhi_epi32(ly, ly); \
|
||||||
|
PLANAR_COMPUTE_0(C0, 0, 1, 4, 3); \
|
||||||
|
PLANAR_STORE_0_ ## D(); \
|
||||||
|
}
|
||||||
|
PRED_PLANAR_0( 8)
|
||||||
|
PRED_PLANAR_0(10)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define PLANAR_LOAD_1_8() \
|
||||||
|
ly = _mm_loadl_epi64((__m128i*)left); \
|
||||||
|
tx = _mm_loadl_epi64((__m128i*)top); \
|
||||||
|
ly = _mm_unpacklo_epi8(ly,_mm_setzero_si128()); \
|
||||||
|
tx = _mm_unpacklo_epi8(tx,_mm_setzero_si128())
|
||||||
|
#define PLANAR_LOAD_1_10() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*)left); \
|
||||||
|
tx = _mm_loadu_si128((__m128i*)top)
|
||||||
|
|
||||||
|
#define PLANAR_COMPUTE_1() \
|
||||||
|
PLANAR_COMPUTE(7, 4)
|
||||||
|
|
||||||
|
#define PLANAR_STORE_1_8() \
|
||||||
|
c0 = _mm_packus_epi16(c0,_mm_setzero_si128()); \
|
||||||
|
_mm_storel_epi64((__m128i*)(src), c0); \
|
||||||
|
src+= stride; \
|
||||||
|
ly = _mm_srli_si128(ly,2)
|
||||||
|
#define PLANAR_STORE_1_10() \
|
||||||
|
_mm_storeu_si128((__m128i*)(src), c0); \
|
||||||
|
src+= stride; \
|
||||||
|
ly = _mm_srli_si128(ly,2)
|
||||||
|
|
||||||
|
#define PRED_PLANAR_1(D) \
|
||||||
|
void pred_planar_1_ ## D ## _sse(uint8_t *_src, const uint8_t *_top, \
|
||||||
|
const uint8_t *_left, ptrdiff_t stride) { \
|
||||||
|
int y; \
|
||||||
|
__m128i ly, l0, tx, ly1; \
|
||||||
|
__m128i tmp1, add, x0, c0, c1; \
|
||||||
|
PLANAR_INIT_ ## D(); \
|
||||||
|
tx = _mm_set1_epi16(top[8]); \
|
||||||
|
l0 = _mm_set1_epi16(left[8]); \
|
||||||
|
add = _mm_set1_epi16(8); \
|
||||||
|
tmp1 = _mm_set_epi16(0,1,2,3,4,5,6,7); \
|
||||||
|
c1 = _mm_mullo_epi16(_mm_set_epi16(8,7,6,5,4,3,2,1), tx); \
|
||||||
|
c1 = _mm_add_epi16(c1,add); \
|
||||||
|
PLANAR_LOAD_1_ ## D(); \
|
||||||
|
for (y = 0; y < 8; y++) { \
|
||||||
|
PLANAR_COMPUTE_1(); \
|
||||||
|
PLANAR_STORE_1_ ## D(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
PRED_PLANAR_1( 8)
|
||||||
|
PRED_PLANAR_1(10)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define PLANAR_LOAD_2_8() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*) left); \
|
||||||
|
tx = _mm_loadu_si128((__m128i*) top); \
|
||||||
|
lh = _mm_unpackhi_epi8(ly,_mm_setzero_si128()); \
|
||||||
|
ly = _mm_unpacklo_epi8(ly,_mm_setzero_si128()); \
|
||||||
|
th = _mm_unpackhi_epi8(tx,_mm_setzero_si128()); \
|
||||||
|
tx = _mm_unpacklo_epi8(tx,_mm_setzero_si128())
|
||||||
|
|
||||||
|
#define PLANAR_LOAD_2_10() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*) left); \
|
||||||
|
lh = _mm_loadu_si128((__m128i*)&left[8]); \
|
||||||
|
tx = _mm_loadu_si128((__m128i*) top); \
|
||||||
|
th = _mm_loadu_si128((__m128i*)&top[8])
|
||||||
|
|
||||||
|
#define PLANAR_COMPUTE_2() \
|
||||||
|
PLANAR_COMPUTE(15, 5)
|
||||||
|
#define PLANAR_COMPUTE_HI_2() \
|
||||||
|
PLANAR_COMPUTE_HI(15, 5)
|
||||||
|
|
||||||
|
#define PLANAR_STORE_2_8() \
|
||||||
|
c0 = _mm_packus_epi16(c0, C0); \
|
||||||
|
_mm_storeu_si128((__m128i*) src, c0); \
|
||||||
|
src+= stride; \
|
||||||
|
ly = _mm_srli_si128(ly,2)
|
||||||
|
#define PLANAR_STORE_2_10() \
|
||||||
|
_mm_storeu_si128((__m128i*) src , c0); \
|
||||||
|
_mm_storeu_si128((__m128i*)&src[8], C0); \
|
||||||
|
src+= stride; \
|
||||||
|
ly = _mm_srli_si128(ly,2)
|
||||||
|
|
||||||
|
#define PRED_PLANAR_2(D) \
|
||||||
|
void pred_planar_2_ ## D ## _sse(uint8_t *_src, const uint8_t *_top, \
|
||||||
|
const uint8_t *_left, ptrdiff_t stride) { \
|
||||||
|
int y, i; \
|
||||||
|
__m128i ly, lh, l0, tx, th, ly1; \
|
||||||
|
__m128i tmp1, tmp2, add, x0, c0, c1, C0, C1; \
|
||||||
|
PLANAR_INIT_ ## D(); \
|
||||||
|
tx = _mm_set1_epi16(top[16]); \
|
||||||
|
l0 = _mm_set1_epi16(left[16]); \
|
||||||
|
add = _mm_set1_epi16(16); \
|
||||||
|
tmp1 = _mm_set_epi16( 8, 9,10,11,12,13,14,15); \
|
||||||
|
tmp2 = _mm_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7); \
|
||||||
|
c1 = _mm_mullo_epi16(_mm_set_epi16( 8, 7, 6, 5, 4, 3, 2, 1), tx); \
|
||||||
|
C1 = _mm_mullo_epi16(_mm_set_epi16(16,15,14,13,12,11,10, 9), tx); \
|
||||||
|
c1 = _mm_add_epi16(c1, add); \
|
||||||
|
C1 = _mm_add_epi16(C1, add); \
|
||||||
|
PLANAR_LOAD_2_ ## D(); \
|
||||||
|
for (i = 0; i < 2; i++) { \
|
||||||
|
for (y = i*8; y < i*8+8; y++) { \
|
||||||
|
PLANAR_COMPUTE_2(); \
|
||||||
|
PLANAR_COMPUTE_HI_2(); \
|
||||||
|
PLANAR_STORE_2_ ## D(); \
|
||||||
|
} \
|
||||||
|
ly = lh; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
PRED_PLANAR_2( 8)
|
||||||
|
PRED_PLANAR_2(10)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define PLANAR_LOAD_3_8() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*) left); \
|
||||||
|
lh = _mm_unpackhi_epi8(ly,_mm_setzero_si128()); \
|
||||||
|
ly = _mm_unpacklo_epi8(ly,_mm_setzero_si128()); \
|
||||||
|
tx = _mm_loadu_si128((__m128i*) top); \
|
||||||
|
th = _mm_unpackhi_epi8(tx,_mm_setzero_si128()); \
|
||||||
|
tx = _mm_unpacklo_epi8(tx,_mm_setzero_si128()); \
|
||||||
|
TX = _mm_loadu_si128((__m128i*)(top + 16)); \
|
||||||
|
TH = _mm_unpackhi_epi8(TX,_mm_setzero_si128()); \
|
||||||
|
TX = _mm_unpacklo_epi8(TX,_mm_setzero_si128())
|
||||||
|
#define PLANAR_LOAD_3_10() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*) left ); \
|
||||||
|
lh = _mm_loadu_si128((__m128i*)&left[8]); \
|
||||||
|
tx = _mm_loadu_si128((__m128i*) top ); \
|
||||||
|
th = _mm_loadu_si128((__m128i*)&top[ 8]); \
|
||||||
|
TX = _mm_loadu_si128((__m128i*)&top[16]); \
|
||||||
|
TH = _mm_loadu_si128((__m128i*)&top[24])
|
||||||
|
|
||||||
|
#define PLANAR_RELOAD_3_8() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*)(left+16)); \
|
||||||
|
lh = _mm_unpackhi_epi8(ly,_mm_setzero_si128()); \
|
||||||
|
ly = _mm_unpacklo_epi8(ly,_mm_setzero_si128())
|
||||||
|
#define PLANAR_RELOAD_3_10() \
|
||||||
|
ly = _mm_loadu_si128((__m128i*)&left[16]); \
|
||||||
|
lh = _mm_loadu_si128((__m128i*)&left[24])
|
||||||
|
|
||||||
|
#define PLANAR_COMPUTE_3() \
|
||||||
|
PLANAR_COMPUTE(31, 6)
|
||||||
|
#define PLANAR_COMPUTE_HI_3() \
|
||||||
|
PLANAR_COMPUTE_HI(31, 6)
|
||||||
|
#define PLANAR_COMPUTE_HI2_3() \
|
||||||
|
c0 = _mm_mullo_epi16(TMP1, ly1); \
|
||||||
|
x0 = _mm_mullo_epi16(_mm_set1_epi16(31 - y), TX); \
|
||||||
|
c0 = _mm_add_epi16(c0, c2); \
|
||||||
|
x0 = _mm_add_epi16(x0, c0); \
|
||||||
|
x0 = _mm_add_epi16(x0, add); \
|
||||||
|
c0 = _mm_srli_epi16(x0, 6)
|
||||||
|
#define PLANAR_COMPUTE_HI3_3() \
|
||||||
|
C0 = _mm_mullo_epi16(TMP2, ly1); \
|
||||||
|
x0 = _mm_mullo_epi16(_mm_set1_epi16(31 - y), TH); \
|
||||||
|
C0 = _mm_add_epi16(C0, C2); \
|
||||||
|
x0 = _mm_add_epi16(x0, C0); \
|
||||||
|
x0 = _mm_add_epi16(x0, add); \
|
||||||
|
C0 = _mm_srli_epi16(x0, 6)
|
||||||
|
|
||||||
|
#define PLANAR_STORE1_3_8() \
|
||||||
|
c0 = _mm_packus_epi16(c0, C0); \
|
||||||
|
_mm_storeu_si128((__m128i*) src, c0)
|
||||||
|
#define PLANAR_STORE2_3_8() \
|
||||||
|
c0 = _mm_packus_epi16(c0, C0); \
|
||||||
|
_mm_storeu_si128((__m128i*) (src + 16), c0); \
|
||||||
|
src+= stride; \
|
||||||
|
ly = _mm_srli_si128(ly, 2)
|
||||||
|
|
||||||
|
#define PLANAR_STORE1_3_10() \
|
||||||
|
_mm_storeu_si128((__m128i*) src , c0); \
|
||||||
|
_mm_storeu_si128((__m128i*)&src[ 8], C0)
|
||||||
|
#define PLANAR_STORE2_3_10() \
|
||||||
|
_mm_storeu_si128((__m128i*)&src[16], c0); \
|
||||||
|
_mm_storeu_si128((__m128i*)&src[24], C0); \
|
||||||
|
src+= stride; \
|
||||||
|
ly = _mm_srli_si128(ly, 2)
|
||||||
|
|
||||||
|
|
||||||
|
#define PRED_PLANAR_3(D) \
|
||||||
|
void pred_planar_3_ ## D ## _sse(uint8_t *_src, const uint8_t *_top, \
|
||||||
|
const uint8_t *_left, ptrdiff_t stride) { \
|
||||||
|
int y, i; \
|
||||||
|
__m128i l0, ly, lh, ly1, tx, th, TX, TH, tmp1, tmp2, TMP1, TMP2; \
|
||||||
|
__m128i x0, c0, c1, c2, C0, C1, C2, add; \
|
||||||
|
PLANAR_INIT_ ## D(); \
|
||||||
|
tx = _mm_set1_epi16(top[32]); \
|
||||||
|
l0 = _mm_set1_epi16(left[32]); \
|
||||||
|
add = _mm_set1_epi16(32); \
|
||||||
|
tmp1 = _mm_set_epi16(24,25,26,27,28,29,30,31); \
|
||||||
|
tmp2 = _mm_set_epi16(16,17,18,19,20,21,22,23); \
|
||||||
|
TMP1 = _mm_set_epi16( 8, 9,10,11,12,13,14,15); \
|
||||||
|
TMP2 = _mm_set_epi16( 0, 1, 2, 3, 4, 5, 6, 7); \
|
||||||
|
c1 = _mm_mullo_epi16(_mm_set_epi16( 8, 7, 6, 5, 4, 3, 2, 1), tx); \
|
||||||
|
C1 = _mm_mullo_epi16(_mm_set_epi16(16,15,14,13,12,11,10, 9), tx); \
|
||||||
|
c2 = _mm_mullo_epi16(_mm_set_epi16(24,23,22,21,20,19,18,17), tx); \
|
||||||
|
C2 = _mm_mullo_epi16(_mm_set_epi16(32,31,30,29,28,27,26,25), tx); \
|
||||||
|
c1 = _mm_add_epi16(c1, add); \
|
||||||
|
C1 = _mm_add_epi16(C1, add); \
|
||||||
|
c2 = _mm_add_epi16(c2, add); \
|
||||||
|
C2 = _mm_add_epi16(C2, add); \
|
||||||
|
PLANAR_LOAD_3_ ## D(); \
|
||||||
|
for (i = 0; i < 4; i++) { \
|
||||||
|
for (y = 0+i*8; y < 8+i*8; y++) { \
|
||||||
|
PLANAR_COMPUTE_3(); \
|
||||||
|
PLANAR_COMPUTE_HI_3(); \
|
||||||
|
PLANAR_STORE1_3_ ## D(); \
|
||||||
|
PLANAR_COMPUTE_HI2_3(); \
|
||||||
|
PLANAR_COMPUTE_HI3_3(); \
|
||||||
|
PLANAR_STORE2_3_ ## D(); \
|
||||||
|
} \
|
||||||
|
if (i == 0 || i == 2) { \
|
||||||
|
ly = lh; \
|
||||||
|
} else { \
|
||||||
|
PLANAR_RELOAD_3_ ## D(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
PRED_PLANAR_3( 8)
|
||||||
|
PRED_PLANAR_3(10)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define STORE8(out, sstep_out) \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[0*sstep_out], m10); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[2*sstep_out], m12); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[4*sstep_out], m11); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[6*sstep_out], m13); \
|
||||||
|
m10 = _mm_unpackhi_epi64(m10, m10); \
|
||||||
|
m12 = _mm_unpackhi_epi64(m12, m12); \
|
||||||
|
m11 = _mm_unpackhi_epi64(m11, m11); \
|
||||||
|
m13 = _mm_unpackhi_epi64(m13, m13); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[1*sstep_out], m10); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[3*sstep_out], m12); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[5*sstep_out], m11); \
|
||||||
|
_mm_storel_epi64((__m128i*)&out[7*sstep_out], m13)
|
||||||
|
|
||||||
|
#define STORE16(out, sstep_out) \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[0*sstep_out], m0); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[1*sstep_out], m1); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[2*sstep_out], m2); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[3*sstep_out], m3); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[4*sstep_out], m4); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[5*sstep_out], m5); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[6*sstep_out], m6); \
|
||||||
|
_mm_storeu_si128((__m128i *) &out[7*sstep_out], m7)
|
||||||
|
|
||||||
|
#define TRANSPOSE4x4_8(in, sstep_in, out, sstep_out) \
|
||||||
|
{ \
|
||||||
|
__m128i m0 = _mm_loadl_epi64((__m128i *) &in[0*sstep_in]); \
|
||||||
|
__m128i m1 = _mm_loadl_epi64((__m128i *) &in[1*sstep_in]); \
|
||||||
|
__m128i m2 = _mm_loadl_epi64((__m128i *) &in[2*sstep_in]); \
|
||||||
|
__m128i m3 = _mm_loadl_epi64((__m128i *) &in[3*sstep_in]); \
|
||||||
|
\
|
||||||
|
__m128i m10 = _mm_unpacklo_epi8(m0, m1); \
|
||||||
|
__m128i m11 = _mm_unpacklo_epi8(m2, m3); \
|
||||||
|
\
|
||||||
|
m0 = _mm_unpacklo_epi16(m10, m11); \
|
||||||
|
\
|
||||||
|
*((uint32_t *) (out+0*sstep_out)) =_mm_cvtsi128_si32(m0); \
|
||||||
|
*((uint32_t *) (out+1*sstep_out)) =_mm_extract_epi32(m0, 1); \
|
||||||
|
*((uint32_t *) (out+2*sstep_out)) =_mm_extract_epi32(m0, 2); \
|
||||||
|
*((uint32_t *) (out+3*sstep_out)) =_mm_extract_epi32(m0, 3); \
|
||||||
|
}
|
||||||
|
#define TRANSPOSE8x8_8(in, sstep_in, out, sstep_out) \
|
||||||
|
{ \
|
||||||
|
__m128i m0 = _mm_loadl_epi64((__m128i *) &in[0*sstep_in]); \
|
||||||
|
__m128i m1 = _mm_loadl_epi64((__m128i *) &in[1*sstep_in]); \
|
||||||
|
__m128i m2 = _mm_loadl_epi64((__m128i *) &in[2*sstep_in]); \
|
||||||
|
__m128i m3 = _mm_loadl_epi64((__m128i *) &in[3*sstep_in]); \
|
||||||
|
__m128i m4 = _mm_loadl_epi64((__m128i *) &in[4*sstep_in]); \
|
||||||
|
__m128i m5 = _mm_loadl_epi64((__m128i *) &in[5*sstep_in]); \
|
||||||
|
__m128i m6 = _mm_loadl_epi64((__m128i *) &in[6*sstep_in]); \
|
||||||
|
__m128i m7 = _mm_loadl_epi64((__m128i *) &in[7*sstep_in]); \
|
||||||
|
\
|
||||||
|
__m128i m10 = _mm_unpacklo_epi8(m0, m1); \
|
||||||
|
__m128i m11 = _mm_unpacklo_epi8(m2, m3); \
|
||||||
|
__m128i m12 = _mm_unpacklo_epi8(m4, m5); \
|
||||||
|
__m128i m13 = _mm_unpacklo_epi8(m6, m7); \
|
||||||
|
\
|
||||||
|
m0 = _mm_unpacklo_epi16(m10, m11); \
|
||||||
|
m1 = _mm_unpacklo_epi16(m12, m13); \
|
||||||
|
m2 = _mm_unpackhi_epi16(m10, m11); \
|
||||||
|
m3 = _mm_unpackhi_epi16(m12, m13); \
|
||||||
|
\
|
||||||
|
m10 = _mm_unpacklo_epi32(m0 , m1 ); \
|
||||||
|
m11 = _mm_unpacklo_epi32(m2 , m3 ); \
|
||||||
|
m12 = _mm_unpackhi_epi32(m0 , m1 ); \
|
||||||
|
m13 = _mm_unpackhi_epi32(m2 , m3 ); \
|
||||||
|
\
|
||||||
|
STORE8(out, sstep_out); \
|
||||||
|
}
|
||||||
|
#define TRANSPOSE16x16_8(in, sstep_in, out, sstep_out) \
|
||||||
|
for (y = 0; y < sstep_in; y+=8) \
|
||||||
|
for (x = 0; x < sstep_in; x+=8) \
|
||||||
|
TRANSPOSE8x8_8((&in[y*sstep_in+x]), sstep_in, (&out[x*sstep_out+y]), sstep_out)
|
||||||
|
#define TRANSPOSE32x32_8(in, sstep_in, out, sstep_out) \
|
||||||
|
for (y = 0; y < sstep_in; y+=8) \
|
||||||
|
for (x = 0; x < sstep_in; x+=8) \
|
||||||
|
TRANSPOSE8x8_8((&in[y*sstep_in+x]), sstep_in, (&out[x*sstep_out+y]), sstep_out)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define TRANSPOSE4x4_10(in, sstep_in, out, sstep_out) \
|
||||||
|
{ \
|
||||||
|
__m128i m0 = _mm_loadl_epi64((__m128i *) &in[0*sstep_in]); \
|
||||||
|
__m128i m1 = _mm_loadl_epi64((__m128i *) &in[1*sstep_in]); \
|
||||||
|
__m128i m2 = _mm_loadl_epi64((__m128i *) &in[2*sstep_in]); \
|
||||||
|
__m128i m3 = _mm_loadl_epi64((__m128i *) &in[3*sstep_in]); \
|
||||||
|
\
|
||||||
|
__m128i m10 = _mm_unpacklo_epi16(m0, m1); \
|
||||||
|
__m128i m11 = _mm_unpacklo_epi16(m2, m3); \
|
||||||
|
\
|
||||||
|
m0 = _mm_unpacklo_epi32(m10, m11); \
|
||||||
|
m1 = _mm_unpackhi_epi32(m10, m11); \
|
||||||
|
\
|
||||||
|
_mm_storel_epi64((__m128i *) (out+0*sstep_out) , m0); \
|
||||||
|
_mm_storel_epi64((__m128i *) (out+1*sstep_out) , _mm_unpackhi_epi64(m0, m0));\
|
||||||
|
_mm_storel_epi64((__m128i *) (out+2*sstep_out) , m1); \
|
||||||
|
_mm_storel_epi64((__m128i *) (out+3*sstep_out) , _mm_unpackhi_epi64(m1, m1));\
|
||||||
|
}
|
||||||
|
#define TRANSPOSE8x8_10(in, sstep_in, out, sstep_out) \
|
||||||
|
{ \
|
||||||
|
__m128i tmp0, tmp1, tmp2, tmp3, src0, src1, src2, src3; \
|
||||||
|
__m128i m0 = _mm_loadu_si128((__m128i *) &in[0*sstep_in]); \
|
||||||
|
__m128i m1 = _mm_loadu_si128((__m128i *) &in[1*sstep_in]); \
|
||||||
|
__m128i m2 = _mm_loadu_si128((__m128i *) &in[2*sstep_in]); \
|
||||||
|
__m128i m3 = _mm_loadu_si128((__m128i *) &in[3*sstep_in]); \
|
||||||
|
__m128i m4 = _mm_loadu_si128((__m128i *) &in[4*sstep_in]); \
|
||||||
|
__m128i m5 = _mm_loadu_si128((__m128i *) &in[5*sstep_in]); \
|
||||||
|
__m128i m6 = _mm_loadu_si128((__m128i *) &in[6*sstep_in]); \
|
||||||
|
__m128i m7 = _mm_loadu_si128((__m128i *) &in[7*sstep_in]); \
|
||||||
|
\
|
||||||
|
tmp0 = _mm_unpacklo_epi16(m0, m1); \
|
||||||
|
tmp1 = _mm_unpacklo_epi16(m2, m3); \
|
||||||
|
tmp2 = _mm_unpacklo_epi16(m4, m5); \
|
||||||
|
tmp3 = _mm_unpacklo_epi16(m6, m7); \
|
||||||
|
src0 = _mm_unpacklo_epi32(tmp0, tmp1); \
|
||||||
|
src1 = _mm_unpacklo_epi32(tmp2, tmp3); \
|
||||||
|
src2 = _mm_unpackhi_epi32(tmp0, tmp1); \
|
||||||
|
src3 = _mm_unpackhi_epi32(tmp2, tmp3); \
|
||||||
|
tmp0 = _mm_unpackhi_epi16(m0, m1); \
|
||||||
|
tmp1 = _mm_unpackhi_epi16(m2, m3); \
|
||||||
|
tmp2 = _mm_unpackhi_epi16(m4, m5); \
|
||||||
|
tmp3 = _mm_unpackhi_epi16(m6, m7); \
|
||||||
|
m0 = _mm_unpacklo_epi64(src0 , src1); \
|
||||||
|
m1 = _mm_unpackhi_epi64(src0 , src1); \
|
||||||
|
m2 = _mm_unpacklo_epi64(src2 , src3); \
|
||||||
|
m3 = _mm_unpackhi_epi64(src2 , src3); \
|
||||||
|
src0 = _mm_unpacklo_epi32(tmp0, tmp1); \
|
||||||
|
src1 = _mm_unpacklo_epi32(tmp2, tmp3); \
|
||||||
|
src2 = _mm_unpackhi_epi32(tmp0, tmp1); \
|
||||||
|
src3 = _mm_unpackhi_epi32(tmp2, tmp3); \
|
||||||
|
m4 = _mm_unpacklo_epi64(src0 , src1); \
|
||||||
|
m5 = _mm_unpackhi_epi64(src0 , src1); \
|
||||||
|
m6 = _mm_unpacklo_epi64(src2 , src3); \
|
||||||
|
m7 = _mm_unpackhi_epi64(src2 , src3); \
|
||||||
|
STORE16(out, sstep_out); \
|
||||||
|
}
|
||||||
|
#define TRANSPOSE16x16_10(in, sstep_in, out, sstep_out) \
|
||||||
|
for (y = 0; y < sstep_in; y+=8) \
|
||||||
|
for (x = 0; x < sstep_in; x+=8) \
|
||||||
|
TRANSPOSE8x8_10((&in[y*sstep_in+x]), sstep_in, (&out[x*sstep_out+y]), sstep_out)
|
||||||
|
#define TRANSPOSE32x32_10(in, sstep_in, out, sstep_out) \
|
||||||
|
for (y = 0; y < sstep_in; y+=8) \
|
||||||
|
for (x = 0; x < sstep_in; x+=8) \
|
||||||
|
TRANSPOSE8x8_10((&in[y*sstep_in+x]), sstep_in, (&out[x*sstep_out+y]), sstep_out)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define ANGULAR_COMPUTE_8(W) \
|
||||||
|
for (x = 0; x < W; x += 8) { \
|
||||||
|
r3 = _mm_set1_epi16((fact << 8) + (32 - fact)); \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*)(&ref[x+idx+1])); \
|
||||||
|
r0 = _mm_srli_si128(r1, 1); \
|
||||||
|
r1 = _mm_unpacklo_epi8(r1, r0); \
|
||||||
|
r1 = _mm_maddubs_epi16(r1, r3); \
|
||||||
|
r1 = _mm_mulhrs_epi16(r1, _mm_set1_epi16(1024)); \
|
||||||
|
r1 = _mm_packus_epi16(r1, r1); \
|
||||||
|
_mm_storel_epi64((__m128i *) &p_src[x], r1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ANGULAR_COMPUTE4_8() \
|
||||||
|
r3 = _mm_set1_epi16((fact << 8) + (32 - fact)); \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*)(&ref[idx+1])); \
|
||||||
|
r0 = _mm_srli_si128(r1, 1); \
|
||||||
|
r1 = _mm_unpacklo_epi8(r1, r0); \
|
||||||
|
r1 = _mm_maddubs_epi16(r1, r3); \
|
||||||
|
r1 = _mm_mulhrs_epi16(r1, _mm_set1_epi16(1024)); \
|
||||||
|
r1 = _mm_packus_epi16(r1, r1); \
|
||||||
|
*((uint32_t *)p_src) = _mm_cvtsi128_si32(r1)
|
||||||
|
#define ANGULAR_COMPUTE8_8() ANGULAR_COMPUTE_8( 8)
|
||||||
|
#define ANGULAR_COMPUTE16_8() ANGULAR_COMPUTE_8(16)
|
||||||
|
#define ANGULAR_COMPUTE32_8() ANGULAR_COMPUTE_8(32)
|
||||||
|
|
||||||
|
#define ANGULAR_COMPUTE_ELSE4_8() \
|
||||||
|
r1 = _mm_loadl_epi64((__m128i*) &ref[idx+1]); \
|
||||||
|
*((uint32_t *)p_src) = _mm_cvtsi128_si32(r1)
|
||||||
|
#define ANGULAR_COMPUTE_ELSE8_8() \
|
||||||
|
r1 = _mm_loadl_epi64((__m128i*) &ref[idx+1]); \
|
||||||
|
_mm_storel_epi64((__m128i *) p_src, r1)
|
||||||
|
#define ANGULAR_COMPUTE_ELSE16_8() \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*) &ref[idx+1]); \
|
||||||
|
_mm_storeu_si128((__m128i *) p_src, r1)
|
||||||
|
#define ANGULAR_COMPUTE_ELSE32_8() \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*) &ref[idx+1]); \
|
||||||
|
_mm_storeu_si128((__m128i *) p_src ,r1); \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*) &ref[idx+17]); \
|
||||||
|
_mm_storeu_si128((__m128i *)&p_src[16] ,r1)
|
||||||
|
|
||||||
|
#define CLIP_PIXEL(src1, src2) \
|
||||||
|
r3 = _mm_loadu_si128((__m128i*)src1); \
|
||||||
|
r1 = _mm_set1_epi16(src1[-1]); \
|
||||||
|
r2 = _mm_set1_epi16(src2[0]); \
|
||||||
|
r0 = _mm_unpacklo_epi8(r3,_mm_setzero_si128()); \
|
||||||
|
r0 = _mm_subs_epi16(r0, r1); \
|
||||||
|
r0 = _mm_srai_epi16(r0, 1); \
|
||||||
|
r0 = _mm_add_epi16(r0, r2)
|
||||||
|
#define CLIP_PIXEL_HI() \
|
||||||
|
r3 = _mm_unpackhi_epi8(r3,_mm_setzero_si128()); \
|
||||||
|
r3 = _mm_subs_epi16(r3, r1); \
|
||||||
|
r3 = _mm_srai_epi16(r3, 1); \
|
||||||
|
r3 = _mm_add_epi16(r3, r2)
|
||||||
|
|
||||||
|
#define CLIP_PIXEL1_4_8() \
|
||||||
|
p_src = src; \
|
||||||
|
CLIP_PIXEL(src2, src1); \
|
||||||
|
r0 = _mm_packus_epi16(r0, r0); \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 0); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 1); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 2); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 3)
|
||||||
|
#define CLIP_PIXEL1_8_8() \
|
||||||
|
CLIP_PIXEL1_4_8(); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 4); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 5); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 6); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 7)
|
||||||
|
#define CLIP_PIXEL1_16_8() \
|
||||||
|
p_src = src; \
|
||||||
|
CLIP_PIXEL(src2, src1); \
|
||||||
|
CLIP_PIXEL_HI(); \
|
||||||
|
r0 = _mm_packus_epi16(r0, r3); \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 0); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 1); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 2); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 3); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 4); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 5); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 6); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 7); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 8); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0, 9); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0,10); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0,11); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0,12); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0,13); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0,14); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((char *) p_src) = _mm_extract_epi8(r0,15)
|
||||||
|
#define CLIP_PIXEL1_32_8()
|
||||||
|
|
||||||
|
#define CLIP_PIXEL2_4_8() \
|
||||||
|
CLIP_PIXEL(src2, src1); \
|
||||||
|
r0 = _mm_packus_epi16(r0, r0); \
|
||||||
|
*((uint32_t *)_src) = _mm_cvtsi128_si32(r0)
|
||||||
|
#define CLIP_PIXEL2_8_8() \
|
||||||
|
CLIP_PIXEL(src2, src1); \
|
||||||
|
r0 = _mm_packus_epi16(r0, r0); \
|
||||||
|
_mm_storel_epi64((__m128i*)_src, r0)
|
||||||
|
#define CLIP_PIXEL2_16_8() \
|
||||||
|
CLIP_PIXEL(src2, src1); \
|
||||||
|
CLIP_PIXEL_HI(); \
|
||||||
|
r0 = _mm_packus_epi16(r0, r3); \
|
||||||
|
_mm_storeu_si128((__m128i*) _src , r0)
|
||||||
|
#define CLIP_PIXEL2_32_8()
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if HAVE_SSE4
|
||||||
|
#define ANGULAR_COMPUTE_10(W) \
|
||||||
|
for (x = 0; x < W; x += 4) { \
|
||||||
|
r3 = _mm_set1_epi32((fact << 16) + (32 - fact)); \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*)(&ref[x+idx+1])); \
|
||||||
|
r0 = _mm_srli_si128(r1, 2); \
|
||||||
|
r1 = _mm_unpacklo_epi16(r1, r0); \
|
||||||
|
r1 = _mm_madd_epi16(r1, r3); \
|
||||||
|
r1 = _mm_mulhrs_epi16(r1, _mm_set1_epi16(1024)); \
|
||||||
|
r1 = _MM_PACKUS_EPI32(r1, r1); \
|
||||||
|
_mm_storel_epi64((__m128i *) &p_src[x], r1); \
|
||||||
|
}
|
||||||
|
#define ANGULAR_COMPUTE4_10() ANGULAR_COMPUTE_10( 4)
|
||||||
|
#define ANGULAR_COMPUTE8_10() ANGULAR_COMPUTE_10( 8)
|
||||||
|
#define ANGULAR_COMPUTE16_10() ANGULAR_COMPUTE_10(16)
|
||||||
|
#define ANGULAR_COMPUTE32_10() ANGULAR_COMPUTE_10(32)
|
||||||
|
|
||||||
|
#define ANGULAR_COMPUTE_ELSE_10(W) \
|
||||||
|
for (x = 0; x < W; x += 8) { \
|
||||||
|
r1 = _mm_loadu_si128((__m128i*)(&ref[x+idx+1])); \
|
||||||
|
_mm_storeu_si128((__m128i *) &p_src[x], r1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ANGULAR_COMPUTE_ELSE4_10() \
|
||||||
|
r1 = _mm_loadl_epi64((__m128i*)(&ref[idx+1])); \
|
||||||
|
_mm_storel_epi64((__m128i *) p_src, r1)
|
||||||
|
|
||||||
|
#define ANGULAR_COMPUTE_ELSE8_10() ANGULAR_COMPUTE_ELSE_10(8)
|
||||||
|
#define ANGULAR_COMPUTE_ELSE16_10() ANGULAR_COMPUTE_ELSE_10(16)
|
||||||
|
#define ANGULAR_COMPUTE_ELSE32_10() ANGULAR_COMPUTE_ELSE_10(32)
|
||||||
|
|
||||||
|
#define CLIP_PIXEL_10() \
|
||||||
|
r0 = _mm_loadu_si128((__m128i*)src2); \
|
||||||
|
r1 = _mm_set1_epi16(src2[-1]); \
|
||||||
|
r2 = _mm_set1_epi16(src1[0]); \
|
||||||
|
r0 = _mm_subs_epi16(r0, r1); \
|
||||||
|
r0 = _mm_srai_epi16(r0, 1); \
|
||||||
|
r0 = _mm_add_epi16(r0, r2)
|
||||||
|
#define CLIP_PIXEL_HI_10() \
|
||||||
|
r3 = _mm_loadu_si128((__m128i*)&src2[8]); \
|
||||||
|
r3 = _mm_subs_epi16(r3, r1); \
|
||||||
|
r3 = _mm_srai_epi16(r3, 1); \
|
||||||
|
r3 = _mm_add_epi16(r3, r2)
|
||||||
|
|
||||||
|
#define CLIP_PIXEL1_4_10() \
|
||||||
|
p_src = src; \
|
||||||
|
CLIP_PIXEL_10(); \
|
||||||
|
r0 = _mm_max_epi16(r0, _mm_setzero_si128()); \
|
||||||
|
r0 = _mm_min_epi16(r0, _mm_set1_epi16(0x03ff)); \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 0); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 1); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 2); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 3)
|
||||||
|
#define CLIP_PIXEL1_8_10() \
|
||||||
|
CLIP_PIXEL1_4_10(); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 4); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 5); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 6); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 7)
|
||||||
|
#define CLIP_PIXEL1_16_10() \
|
||||||
|
p_src = src; \
|
||||||
|
CLIP_PIXEL_10(); \
|
||||||
|
CLIP_PIXEL_HI_10(); \
|
||||||
|
r0 = _mm_max_epi16(r0, _mm_setzero_si128()); \
|
||||||
|
r0 = _mm_min_epi16(r0, _mm_set1_epi16(0x03ff)); \
|
||||||
|
r3 = _mm_max_epi16(r3, _mm_setzero_si128()); \
|
||||||
|
r3 = _mm_min_epi16(r3, _mm_set1_epi16(0x03ff)); \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 0); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 1); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 2); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 3); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 4); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 5); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 6); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r0, 7); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 0); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 1); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 2); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 3); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 4); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 5); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 6); \
|
||||||
|
p_src += stride; \
|
||||||
|
*((uint16_t *) p_src) = _mm_extract_epi16(r3, 7)
|
||||||
|
#define CLIP_PIXEL1_32_10()
|
||||||
|
|
||||||
|
#define CLIP_PIXEL2_4_10() \
|
||||||
|
CLIP_PIXEL_10(); \
|
||||||
|
r0 = _mm_max_epi16(r0, _mm_setzero_si128()); \
|
||||||
|
r0 = _mm_min_epi16(r0, _mm_set1_epi16(0x03ff)); \
|
||||||
|
_mm_storel_epi64((__m128i*) _src , r0)
|
||||||
|
#define CLIP_PIXEL2_8_10() \
|
||||||
|
CLIP_PIXEL_10(); \
|
||||||
|
r0 = _mm_max_epi16(r0, _mm_setzero_si128()); \
|
||||||
|
r0 = _mm_min_epi16(r0, _mm_set1_epi16(0x03ff)); \
|
||||||
|
_mm_storeu_si128((__m128i*) _src , r0)
|
||||||
|
#define CLIP_PIXEL2_16_10() \
|
||||||
|
CLIP_PIXEL_10(); \
|
||||||
|
CLIP_PIXEL_HI_10(); \
|
||||||
|
r0 = _mm_max_epi16(r0, _mm_setzero_si128()); \
|
||||||
|
r0 = _mm_min_epi16(r0, _mm_set1_epi16(0x03ff)); \
|
||||||
|
r3 = _mm_max_epi16(r3, _mm_setzero_si128()); \
|
||||||
|
r3 = _mm_min_epi16(r3, _mm_set1_epi16(0x03ff)); \
|
||||||
|
_mm_storeu_si128((__m128i*) p_out , r0); \
|
||||||
|
_mm_storeu_si128((__m128i*) &p_out[8], r3);
|
||||||
|
|
||||||
|
#define CLIP_PIXEL2_32_10()
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#define PRED_ANGULAR_INIT_8(W) \
|
||||||
|
const uint8_t *src1; \
|
||||||
|
const uint8_t *src2; \
|
||||||
|
uint8_t *ref, *p_src, *src, *p_out; \
|
||||||
|
uint8_t src_tmp[W*W]; \
|
||||||
|
if (mode >= 18) { \
|
||||||
|
src1 = (const uint8_t*) _top; \
|
||||||
|
src2 = (const uint8_t*) _left; \
|
||||||
|
src = (uint8_t*) _src; \
|
||||||
|
stride = _stride; \
|
||||||
|
p_src = src; \
|
||||||
|
} else { \
|
||||||
|
src1 = (const uint8_t*) _left; \
|
||||||
|
src2 = (const uint8_t*) _top; \
|
||||||
|
src = &src_tmp[0]; \
|
||||||
|
stride = W; \
|
||||||
|
p_src = src; \
|
||||||
|
} \
|
||||||
|
p_out = (uint8_t*) _src; \
|
||||||
|
ref = (uint8_t*) (src1 - 1)
|
||||||
|
#define PRED_ANGULAR_INIT_10(W) \
|
||||||
|
const uint16_t *src1; \
|
||||||
|
const uint16_t *src2; \
|
||||||
|
uint16_t *ref, *p_src, *src, *p_out; \
|
||||||
|
uint16_t src_tmp[W*W]; \
|
||||||
|
if (mode >= 18) { \
|
||||||
|
src1 = (const uint16_t*) _top; \
|
||||||
|
src2 = (const uint16_t*) _left; \
|
||||||
|
src = (uint16_t*) _src; \
|
||||||
|
stride = _stride; \
|
||||||
|
p_src = src; \
|
||||||
|
} else { \
|
||||||
|
src1 = (const uint16_t*) _left; \
|
||||||
|
src2 = (const uint16_t*) _top; \
|
||||||
|
src = &src_tmp[0]; \
|
||||||
|
stride = W; \
|
||||||
|
p_src = src; \
|
||||||
|
} \
|
||||||
|
p_out = (uint16_t*) _src; \
|
||||||
|
ref = (uint16_t*) (src1 - 1)
|
||||||
|
|
||||||
|
#define PRED_ANGULAR_WAR() \
|
||||||
|
int y; \
|
||||||
|
__m128i r0, r1, r3
|
||||||
|
|
||||||
|
#define PRED_ANGULAR_WAR4_8() \
|
||||||
|
PRED_ANGULAR_WAR(); \
|
||||||
|
__m128i r2
|
||||||
|
#define PRED_ANGULAR_WAR8_8() \
|
||||||
|
PRED_ANGULAR_WAR4_8(); \
|
||||||
|
int x
|
||||||
|
#define PRED_ANGULAR_WAR16_8() \
|
||||||
|
PRED_ANGULAR_WAR8_8()
|
||||||
|
#define PRED_ANGULAR_WAR32_8() \
|
||||||
|
PRED_ANGULAR_WAR(); \
|
||||||
|
int x
|
||||||
|
|
||||||
|
#define PRED_ANGULAR_WAR4_10() PRED_ANGULAR_WAR8_8()
|
||||||
|
#define PRED_ANGULAR_WAR8_10() PRED_ANGULAR_WAR8_8()
|
||||||
|
#define PRED_ANGULAR_WAR16_10() PRED_ANGULAR_WAR16_8()
|
||||||
|
#define PRED_ANGULAR_WAR32_10() PRED_ANGULAR_WAR32_8()
|
||||||
|
|
||||||
|
#define PRED_ANGULAR(W, D) \
|
||||||
|
static av_always_inline void pred_angular_ ## W ##_ ## D ## _sse(uint8_t *_src,\
|
||||||
|
const uint8_t *_top, const uint8_t *_left, ptrdiff_t _stride, int c_idx, int mode) {\
|
||||||
|
const int intra_pred_angle[] = { \
|
||||||
|
32, 26, 21, 17, 13, 9, 5, 2, 0, -2, -5, -9,-13,-17,-21,-26, \
|
||||||
|
-32,-26,-21,-17,-13, -9, -5, -2, 0, 2, 5, 9, 13, 17, 21, 26, 32 \
|
||||||
|
}; \
|
||||||
|
const int inv_angle[] = { \
|
||||||
|
-4096, -1638, -910, -630, -482, -390, -315, -256, -315, -390, -482, \
|
||||||
|
-630, -910, -1638, -4096 \
|
||||||
|
}; \
|
||||||
|
PRED_ANGULAR_WAR ## W ## _ ## D(); \
|
||||||
|
int angle = intra_pred_angle[mode-2]; \
|
||||||
|
int angle_i = angle; \
|
||||||
|
int last = (W * angle) >> 5; \
|
||||||
|
int stride; \
|
||||||
|
PRED_ANGULAR_INIT_ ## D(W); \
|
||||||
|
if (angle < 0 && last < -1) { \
|
||||||
|
for (y = last; y <= -1; y++) \
|
||||||
|
ref[y] = src2[-1 + ((y * inv_angle[mode-11] + 128) >> 8)]; \
|
||||||
|
} \
|
||||||
|
for (y = 0; y < W; y++) { \
|
||||||
|
int idx = (angle_i) >> 5; \
|
||||||
|
int fact = (angle_i) & 31; \
|
||||||
|
if (fact) { \
|
||||||
|
ANGULAR_COMPUTE ## W ## _ ## D(); \
|
||||||
|
} else { \
|
||||||
|
ANGULAR_COMPUTE_ELSE ## W ## _ ## D(); \
|
||||||
|
} \
|
||||||
|
angle_i += angle; \
|
||||||
|
p_src += stride; \
|
||||||
|
} \
|
||||||
|
if (mode >= 18) { \
|
||||||
|
if (mode == 26 && c_idx == 0) { \
|
||||||
|
CLIP_PIXEL1_ ## W ## _ ## D(); \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
TRANSPOSE ## W ## x ## W ## _ ## D(src_tmp, W, p_out, _stride); \
|
||||||
|
if (mode == 10 && c_idx == 0) { \
|
||||||
|
CLIP_PIXEL2_ ## W ## _ ## D(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
PRED_ANGULAR( 4, 8)
|
||||||
|
PRED_ANGULAR( 8, 8)
|
||||||
|
PRED_ANGULAR(16, 8)
|
||||||
|
PRED_ANGULAR(32, 8)
|
||||||
|
|
||||||
|
PRED_ANGULAR( 4,10)
|
||||||
|
PRED_ANGULAR( 8,10)
|
||||||
|
PRED_ANGULAR(16,10)
|
||||||
|
PRED_ANGULAR(32,10)
|
||||||
|
|
||||||
|
void pred_angular_0_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_4_8_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
void pred_angular_1_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_8_8_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
void pred_angular_2_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_16_8_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
void pred_angular_3_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_32_8_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pred_angular_0_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_4_10_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
void pred_angular_1_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_8_10_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
void pred_angular_2_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_16_10_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
void pred_angular_3_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left,
|
||||||
|
ptrdiff_t _stride, int c_idx, int mode) {
|
||||||
|
pred_angular_32_10_sse(_src, _top, _left, _stride, c_idx, mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC pop_options
|
||||||
|
#endif
|
|
@ -263,4 +263,24 @@ void ff_hevc_add_residual_32_10_sse2(uint8_t *dst, const int16_t *res, ptrdiff_t
|
||||||
void ff_hevc_add_residual_16_10_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
void ff_hevc_add_residual_16_10_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||||
void ff_hevc_add_residual_32_10_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
void ff_hevc_add_residual_32_10_avx2(uint8_t *dst, const int16_t *res, ptrdiff_t stride);
|
||||||
|
|
||||||
|
void ff_hevc_transform_4x4_luma_8_sse2(int16_t *coeffs);
|
||||||
|
void ff_hevc_transform_4x4_luma_10_sse2(int16_t *coeffs);
|
||||||
|
void ff_hevc_transform_4x4_luma_12_sse2(int16_t *coeffs);
|
||||||
|
|
||||||
|
#define IDCT_FUNC(s, b) void ff_hevc_transform_ ## s ## x ## s ##_## b ##_sse2\
|
||||||
|
(int16_t *coeffs, int col_limit);
|
||||||
|
|
||||||
|
IDCT_FUNC(4, 8)
|
||||||
|
IDCT_FUNC(4, 10)
|
||||||
|
IDCT_FUNC(4, 12)
|
||||||
|
IDCT_FUNC(8, 8)
|
||||||
|
IDCT_FUNC(8, 10)
|
||||||
|
IDCT_FUNC(8, 12)
|
||||||
|
IDCT_FUNC(16, 8)
|
||||||
|
IDCT_FUNC(16, 10)
|
||||||
|
IDCT_FUNC(16, 12)
|
||||||
|
IDCT_FUNC(32, 8)
|
||||||
|
IDCT_FUNC(32, 10)
|
||||||
|
IDCT_FUNC(32, 12)
|
||||||
|
|
||||||
#endif // AVCODEC_X86_HEVCDSP_H
|
#endif // AVCODEC_X86_HEVCDSP_H
|
||||||
|
|
|
@ -835,6 +835,13 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth)
|
||||||
c->add_residual[1] = ff_hevc_add_residual_8_8_sse2;
|
c->add_residual[1] = ff_hevc_add_residual_8_8_sse2;
|
||||||
c->add_residual[2] = ff_hevc_add_residual_16_8_sse2;
|
c->add_residual[2] = ff_hevc_add_residual_16_8_sse2;
|
||||||
c->add_residual[3] = ff_hevc_add_residual_32_8_sse2;
|
c->add_residual[3] = ff_hevc_add_residual_32_8_sse2;
|
||||||
|
|
||||||
|
/* intrinsics */
|
||||||
|
c->transform_4x4_luma = ff_hevc_transform_4x4_luma_8_sse2;
|
||||||
|
if (!ARCH_X86_64) {
|
||||||
|
c->idct[2] = ff_hevc_transform_16x16_8_sse2;
|
||||||
|
c->idct[3] = ff_hevc_transform_32x32_8_sse2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (EXTERNAL_SSSE3(cpu_flags)) {
|
if (EXTERNAL_SSSE3(cpu_flags)) {
|
||||||
if(ARCH_X86_64) {
|
if(ARCH_X86_64) {
|
||||||
|
@ -1010,6 +1017,13 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth)
|
||||||
c->add_residual[1] = ff_hevc_add_residual_8_10_sse2;
|
c->add_residual[1] = ff_hevc_add_residual_8_10_sse2;
|
||||||
c->add_residual[2] = ff_hevc_add_residual_16_10_sse2;
|
c->add_residual[2] = ff_hevc_add_residual_16_10_sse2;
|
||||||
c->add_residual[3] = ff_hevc_add_residual_32_10_sse2;
|
c->add_residual[3] = ff_hevc_add_residual_32_10_sse2;
|
||||||
|
|
||||||
|
/* intrinsics */
|
||||||
|
c->transform_4x4_luma = ff_hevc_transform_4x4_luma_10_sse2;
|
||||||
|
if (!ARCH_X86_64) {
|
||||||
|
c->idct[2] = ff_hevc_transform_16x16_10_sse2;
|
||||||
|
c->idct[3] = ff_hevc_transform_32x32_10_sse2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) {
|
if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) {
|
||||||
c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_ssse3;
|
c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_ssse3;
|
||||||
|
@ -1215,6 +1229,13 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth)
|
||||||
c->idct_dc[1] = ff_hevc_idct_8x8_dc_12_sse2;
|
c->idct_dc[1] = ff_hevc_idct_8x8_dc_12_sse2;
|
||||||
c->idct_dc[2] = ff_hevc_idct_16x16_dc_12_sse2;
|
c->idct_dc[2] = ff_hevc_idct_16x16_dc_12_sse2;
|
||||||
c->idct_dc[3] = ff_hevc_idct_32x32_dc_12_sse2;
|
c->idct_dc[3] = ff_hevc_idct_32x32_dc_12_sse2;
|
||||||
|
|
||||||
|
/* intrinsics */
|
||||||
|
c->transform_4x4_luma = ff_hevc_transform_4x4_luma_12_sse2;
|
||||||
|
c->idct[0] = ff_hevc_transform_4x4_12_sse2;
|
||||||
|
c->idct[1] = ff_hevc_transform_8x8_12_sse2;
|
||||||
|
c->idct[2] = ff_hevc_transform_16x16_12_sse2;
|
||||||
|
c->idct[3] = ff_hevc_transform_32x32_12_sse2;
|
||||||
}
|
}
|
||||||
if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) {
|
if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) {
|
||||||
c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_ssse3;
|
c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_ssse3;
|
||||||
|
@ -1252,3 +1273,37 @@ void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "libavcodec/hevcpred.h"
|
||||||
|
#include "libavcodec/x86/hevcpred.h"
|
||||||
|
|
||||||
|
#undef FUNC
|
||||||
|
#define FUNC(a, depth) a ## _ ## depth ## _sse
|
||||||
|
|
||||||
|
#define HEVC_PRED(depth) \
|
||||||
|
hpc->pred_planar[0] = FUNC(pred_planar_0, depth); \
|
||||||
|
hpc->pred_planar[1] = FUNC(pred_planar_1, depth); \
|
||||||
|
hpc->pred_planar[2] = FUNC(pred_planar_2, depth); \
|
||||||
|
hpc->pred_planar[3] = FUNC(pred_planar_3, depth); \
|
||||||
|
hpc->pred_angular[0] = FUNC(pred_angular_0, depth); \
|
||||||
|
hpc->pred_angular[1] = FUNC(pred_angular_1, depth); \
|
||||||
|
hpc->pred_angular[2] = FUNC(pred_angular_2, depth); \
|
||||||
|
hpc->pred_angular[3] = FUNC(pred_angular_3, depth)
|
||||||
|
|
||||||
|
void ff_hevc_pred_init_x86(HEVCPredContext *hpc, int bit_depth)
|
||||||
|
{
|
||||||
|
int mm_flags = av_get_cpu_flags();
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
if (bit_depth == 8) {
|
||||||
|
if (EXTERNAL_SSE4(mm_flags)) {
|
||||||
|
HEVC_PRED(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bit_depth == 10) {
|
||||||
|
if (EXTERNAL_SSE4(mm_flags)) {
|
||||||
|
HEVC_PRED(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef AVCODEC_X86_HEVCPRED_H
|
||||||
|
#define AVCODEC_X86_HEVCPRED_H
|
||||||
|
|
||||||
|
void pred_planar_0_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
void pred_planar_1_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
void pred_planar_2_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
void pred_planar_3_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
|
||||||
|
void pred_angular_0_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
void pred_angular_1_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
void pred_angular_2_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
void pred_angular_3_8_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
|
||||||
|
void pred_planar_0_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
void pred_planar_1_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
void pred_planar_2_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
void pred_planar_3_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride);
|
||||||
|
|
||||||
|
void pred_angular_0_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
void pred_angular_1_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
void pred_angular_2_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
void pred_angular_3_10_sse(uint8_t *_src, const uint8_t *_top, const uint8_t *_left, ptrdiff_t stride, int c_idx, int mode);
|
||||||
|
|
||||||
|
#endif // AVCODEC_X86_HEVCPRED_H
|
|
@ -801,5 +801,5 @@ const FFOutputFormat ff_pulse_muxer = {
|
||||||
.p.flags = AVFMT_NOFILE,
|
.p.flags = AVFMT_NOFILE,
|
||||||
#endif
|
#endif
|
||||||
.p.priv_class = &pulse_muxer_class,
|
.p.priv_class = &pulse_muxer_class,
|
||||||
.flags_internal = FF_FMT_ALLOW_FLUSH,
|
.flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,5 +6,6 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_backend_common.o
|
||||||
|
|
||||||
DNN-OBJS-$(CONFIG_LIBTENSORFLOW) += dnn/dnn_backend_tf.o
|
DNN-OBJS-$(CONFIG_LIBTENSORFLOW) += dnn/dnn_backend_tf.o
|
||||||
DNN-OBJS-$(CONFIG_LIBOPENVINO) += dnn/dnn_backend_openvino.o
|
DNN-OBJS-$(CONFIG_LIBOPENVINO) += dnn/dnn_backend_openvino.o
|
||||||
|
DNN-OBJS-$(CONFIG_LIBTORCH) += dnn/dnn_backend_torch.o
|
||||||
|
|
||||||
OBJS-$(CONFIG_DNN) += $(DNN-OBJS-yes)
|
OBJS-$(CONFIG_DNN) += $(DNN-OBJS-yes)
|
||||||
|
|
|
@ -0,0 +1,597 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* DNN Torch backend implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <torch/torch.h>
|
||||||
|
#include <torch/script.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "../internal.h"
|
||||||
|
#include "dnn_io_proc.h"
|
||||||
|
#include "dnn_backend_common.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "safe_queue.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct THOptions{
|
||||||
|
char *device_name;
|
||||||
|
int optimize;
|
||||||
|
} THOptions;
|
||||||
|
|
||||||
|
typedef struct THContext {
|
||||||
|
const AVClass *c_class;
|
||||||
|
THOptions options;
|
||||||
|
} THContext;
|
||||||
|
|
||||||
|
typedef struct THModel {
|
||||||
|
THContext ctx;
|
||||||
|
DNNModel *model;
|
||||||
|
torch::jit::Module *jit_model;
|
||||||
|
SafeQueue *request_queue;
|
||||||
|
Queue *task_queue;
|
||||||
|
Queue *lltask_queue;
|
||||||
|
} THModel;
|
||||||
|
|
||||||
|
typedef struct THInferRequest {
|
||||||
|
torch::Tensor *output;
|
||||||
|
torch::Tensor *input_tensor;
|
||||||
|
} THInferRequest;
|
||||||
|
|
||||||
|
typedef struct THRequestItem {
|
||||||
|
THInferRequest *infer_request;
|
||||||
|
LastLevelTaskItem *lltask;
|
||||||
|
DNNAsyncExecModule exec_module;
|
||||||
|
} THRequestItem;
|
||||||
|
|
||||||
|
|
||||||
|
#define OFFSET(x) offsetof(THContext, x)
|
||||||
|
#define FLAGS AV_OPT_FLAG_FILTERING_PARAM
|
||||||
|
static const AVOption dnn_th_options[] = {
|
||||||
|
{ "device", "device to run model", OFFSET(options.device_name), AV_OPT_TYPE_STRING, { .str = "cpu" }, 0, 0, FLAGS },
|
||||||
|
{ "optimize", "turn on graph executor optimization", OFFSET(options.optimize), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
AVFILTER_DEFINE_CLASS(dnn_th);
|
||||||
|
|
||||||
|
static int extract_lltask_from_task(TaskItem *task, Queue *lltask_queue)
|
||||||
|
{
|
||||||
|
THModel *th_model = (THModel *)task->model;
|
||||||
|
THContext *ctx = &th_model->ctx;
|
||||||
|
LastLevelTaskItem *lltask = (LastLevelTaskItem *)av_malloc(sizeof(*lltask));
|
||||||
|
if (!lltask) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to allocate memory for LastLevelTaskItem\n");
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
task->inference_todo = 1;
|
||||||
|
task->inference_done = 0;
|
||||||
|
lltask->task = task;
|
||||||
|
if (ff_queue_push_back(lltask_queue, lltask) < 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to push back lltask_queue.\n");
|
||||||
|
av_freep(&lltask);
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void th_free_request(THInferRequest *request)
|
||||||
|
{
|
||||||
|
if (!request)
|
||||||
|
return;
|
||||||
|
if (request->output) {
|
||||||
|
delete(request->output);
|
||||||
|
request->output = NULL;
|
||||||
|
}
|
||||||
|
if (request->input_tensor) {
|
||||||
|
delete(request->input_tensor);
|
||||||
|
request->input_tensor = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void destroy_request_item(THRequestItem **arg)
|
||||||
|
{
|
||||||
|
THRequestItem *item;
|
||||||
|
if (!arg || !*arg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
item = *arg;
|
||||||
|
th_free_request(item->infer_request);
|
||||||
|
av_freep(&item->infer_request);
|
||||||
|
av_freep(&item->lltask);
|
||||||
|
ff_dnn_async_module_cleanup(&item->exec_module);
|
||||||
|
av_freep(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dnn_free_model_th(DNNModel **model)
|
||||||
|
{
|
||||||
|
THModel *th_model;
|
||||||
|
if (!model || !*model)
|
||||||
|
return;
|
||||||
|
|
||||||
|
th_model = (THModel *) (*model)->model;
|
||||||
|
while (ff_safe_queue_size(th_model->request_queue) != 0) {
|
||||||
|
THRequestItem *item = (THRequestItem *)ff_safe_queue_pop_front(th_model->request_queue);
|
||||||
|
destroy_request_item(&item);
|
||||||
|
}
|
||||||
|
ff_safe_queue_destroy(th_model->request_queue);
|
||||||
|
|
||||||
|
while (ff_queue_size(th_model->lltask_queue) != 0) {
|
||||||
|
LastLevelTaskItem *item = (LastLevelTaskItem *)ff_queue_pop_front(th_model->lltask_queue);
|
||||||
|
av_freep(&item);
|
||||||
|
}
|
||||||
|
ff_queue_destroy(th_model->lltask_queue);
|
||||||
|
|
||||||
|
while (ff_queue_size(th_model->task_queue) != 0) {
|
||||||
|
TaskItem *item = (TaskItem *)ff_queue_pop_front(th_model->task_queue);
|
||||||
|
av_frame_free(&item->in_frame);
|
||||||
|
av_frame_free(&item->out_frame);
|
||||||
|
av_freep(&item);
|
||||||
|
}
|
||||||
|
ff_queue_destroy(th_model->task_queue);
|
||||||
|
delete th_model->jit_model;
|
||||||
|
av_opt_free(&th_model->ctx);
|
||||||
|
av_freep(&th_model);
|
||||||
|
av_freep(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_input_th(void *model, DNNData *input, const char *input_name)
|
||||||
|
{
|
||||||
|
input->dt = DNN_FLOAT;
|
||||||
|
input->order = DCO_RGB;
|
||||||
|
input->layout = DL_NCHW;
|
||||||
|
input->dims[0] = 1;
|
||||||
|
input->dims[1] = 3;
|
||||||
|
input->dims[2] = -1;
|
||||||
|
input->dims[3] = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deleter(void *arg)
|
||||||
|
{
|
||||||
|
av_freep(&arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fill_model_input_th(THModel *th_model, THRequestItem *request)
|
||||||
|
{
|
||||||
|
LastLevelTaskItem *lltask = NULL;
|
||||||
|
TaskItem *task = NULL;
|
||||||
|
THInferRequest *infer_request = NULL;
|
||||||
|
DNNData input = { 0 };
|
||||||
|
THContext *ctx = &th_model->ctx;
|
||||||
|
int ret, width_idx, height_idx, channel_idx;
|
||||||
|
|
||||||
|
lltask = (LastLevelTaskItem *)ff_queue_pop_front(th_model->lltask_queue);
|
||||||
|
if (!lltask) {
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
request->lltask = lltask;
|
||||||
|
task = lltask->task;
|
||||||
|
infer_request = request->infer_request;
|
||||||
|
|
||||||
|
ret = get_input_th(th_model, &input, NULL);
|
||||||
|
if ( ret != 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
width_idx = dnn_get_width_idx_by_layout(input.layout);
|
||||||
|
height_idx = dnn_get_height_idx_by_layout(input.layout);
|
||||||
|
channel_idx = dnn_get_channel_idx_by_layout(input.layout);
|
||||||
|
input.dims[height_idx] = task->in_frame->height;
|
||||||
|
input.dims[width_idx] = task->in_frame->width;
|
||||||
|
input.data = av_malloc(input.dims[height_idx] * input.dims[width_idx] *
|
||||||
|
input.dims[channel_idx] * sizeof(float));
|
||||||
|
if (!input.data)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
infer_request->input_tensor = new torch::Tensor();
|
||||||
|
infer_request->output = new torch::Tensor();
|
||||||
|
|
||||||
|
switch (th_model->model->func_type) {
|
||||||
|
case DFT_PROCESS_FRAME:
|
||||||
|
input.scale = 255;
|
||||||
|
if (task->do_ioproc) {
|
||||||
|
if (th_model->model->frame_pre_proc != NULL) {
|
||||||
|
th_model->model->frame_pre_proc(task->in_frame, &input, th_model->model->filter_ctx);
|
||||||
|
} else {
|
||||||
|
ff_proc_from_frame_to_dnn(task->in_frame, &input, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
avpriv_report_missing_feature(NULL, "model function type %d", th_model->model->func_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*infer_request->input_tensor = torch::from_blob(input.data,
|
||||||
|
{1, input.dims[channel_idx], input.dims[height_idx], input.dims[width_idx]},
|
||||||
|
deleter, torch::kFloat32);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
th_free_request(infer_request);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int th_start_inference(void *args)
|
||||||
|
{
|
||||||
|
THRequestItem *request = (THRequestItem *)args;
|
||||||
|
THInferRequest *infer_request = NULL;
|
||||||
|
LastLevelTaskItem *lltask = NULL;
|
||||||
|
TaskItem *task = NULL;
|
||||||
|
THModel *th_model = NULL;
|
||||||
|
THContext *ctx = NULL;
|
||||||
|
std::vector<torch::jit::IValue> inputs;
|
||||||
|
torch::NoGradGuard no_grad;
|
||||||
|
|
||||||
|
if (!request) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "THRequestItem is NULL\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
infer_request = request->infer_request;
|
||||||
|
lltask = request->lltask;
|
||||||
|
task = lltask->task;
|
||||||
|
th_model = (THModel *)task->model;
|
||||||
|
ctx = &th_model->ctx;
|
||||||
|
|
||||||
|
if (ctx->options.optimize)
|
||||||
|
torch::jit::setGraphExecutorOptimize(true);
|
||||||
|
else
|
||||||
|
torch::jit::setGraphExecutorOptimize(false);
|
||||||
|
|
||||||
|
if (!infer_request->input_tensor || !infer_request->output) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "input or output tensor is NULL\n");
|
||||||
|
return DNN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
inputs.push_back(*infer_request->input_tensor);
|
||||||
|
|
||||||
|
*infer_request->output = th_model->jit_model->forward(inputs).toTensor();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void infer_completion_callback(void *args) {
|
||||||
|
THRequestItem *request = (THRequestItem*)args;
|
||||||
|
LastLevelTaskItem *lltask = request->lltask;
|
||||||
|
TaskItem *task = lltask->task;
|
||||||
|
DNNData outputs = { 0 };
|
||||||
|
THInferRequest *infer_request = request->infer_request;
|
||||||
|
THModel *th_model = (THModel *)task->model;
|
||||||
|
torch::Tensor *output = infer_request->output;
|
||||||
|
|
||||||
|
c10::IntArrayRef sizes = output->sizes();
|
||||||
|
outputs.order = DCO_RGB;
|
||||||
|
outputs.layout = DL_NCHW;
|
||||||
|
outputs.dt = DNN_FLOAT;
|
||||||
|
if (sizes.size() == 4) {
|
||||||
|
// 4 dimensions: [batch_size, channel, height, width]
|
||||||
|
// this format of data is normally used for video frame SR
|
||||||
|
outputs.dims[0] = sizes.at(0); // N
|
||||||
|
outputs.dims[1] = sizes.at(1); // C
|
||||||
|
outputs.dims[2] = sizes.at(2); // H
|
||||||
|
outputs.dims[3] = sizes.at(3); // W
|
||||||
|
} else {
|
||||||
|
avpriv_report_missing_feature(&th_model->ctx, "Support of this kind of model");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (th_model->model->func_type) {
|
||||||
|
case DFT_PROCESS_FRAME:
|
||||||
|
if (task->do_ioproc) {
|
||||||
|
outputs.scale = 255;
|
||||||
|
outputs.data = output->data_ptr();
|
||||||
|
if (th_model->model->frame_post_proc != NULL) {
|
||||||
|
th_model->model->frame_post_proc(task->out_frame, &outputs, th_model->model->filter_ctx);
|
||||||
|
} else {
|
||||||
|
ff_proc_from_dnn_to_frame(task->out_frame, &outputs, &th_model->ctx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
task->out_frame->width = outputs.dims[dnn_get_width_idx_by_layout(outputs.layout)];
|
||||||
|
task->out_frame->height = outputs.dims[dnn_get_height_idx_by_layout(outputs.layout)];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
avpriv_report_missing_feature(&th_model->ctx, "model function type %d", th_model->model->func_type);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
task->inference_done++;
|
||||||
|
av_freep(&request->lltask);
|
||||||
|
err:
|
||||||
|
th_free_request(infer_request);
|
||||||
|
|
||||||
|
if (ff_safe_queue_push_back(th_model->request_queue, request) < 0) {
|
||||||
|
destroy_request_item(&request);
|
||||||
|
av_log(&th_model->ctx, AV_LOG_ERROR, "Unable to push back request_queue when failed to start inference.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int execute_model_th(THRequestItem *request, Queue *lltask_queue)
|
||||||
|
{
|
||||||
|
THModel *th_model = NULL;
|
||||||
|
LastLevelTaskItem *lltask;
|
||||||
|
TaskItem *task = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (ff_queue_size(lltask_queue) == 0) {
|
||||||
|
destroy_request_item(&request);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lltask = (LastLevelTaskItem *)ff_queue_peek_front(lltask_queue);
|
||||||
|
if (lltask == NULL) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Failed to get LastLevelTaskItem\n");
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
task = lltask->task;
|
||||||
|
th_model = (THModel *)task->model;
|
||||||
|
|
||||||
|
ret = fill_model_input_th(th_model, request);
|
||||||
|
if ( ret != 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (task->async) {
|
||||||
|
avpriv_report_missing_feature(&th_model->ctx, "LibTorch async");
|
||||||
|
} else {
|
||||||
|
ret = th_start_inference((void *)(request));
|
||||||
|
if (ret != 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
infer_completion_callback(request);
|
||||||
|
return (task->inference_done == task->inference_todo) ? 0 : DNN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
th_free_request(request->infer_request);
|
||||||
|
if (ff_safe_queue_push_back(th_model->request_queue, request) < 0) {
|
||||||
|
destroy_request_item(&request);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_output_th(void *model, const char *input_name, int input_width, int input_height,
|
||||||
|
const char *output_name, int *output_width, int *output_height)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
THModel *th_model = (THModel*) model;
|
||||||
|
THContext *ctx = &th_model->ctx;
|
||||||
|
TaskItem task = { 0 };
|
||||||
|
THRequestItem *request = NULL;
|
||||||
|
DNNExecBaseParams exec_params = {
|
||||||
|
.input_name = input_name,
|
||||||
|
.output_names = &output_name,
|
||||||
|
.nb_output = 1,
|
||||||
|
.in_frame = NULL,
|
||||||
|
.out_frame = NULL,
|
||||||
|
};
|
||||||
|
ret = ff_dnn_fill_gettingoutput_task(&task, &exec_params, th_model, input_height, input_width, ctx);
|
||||||
|
if ( ret != 0) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = extract_lltask_from_task(&task, th_model->lltask_queue);
|
||||||
|
if ( ret != 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to extract last level task from task.\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = (THRequestItem*) ff_safe_queue_pop_front(th_model->request_queue);
|
||||||
|
if (!request) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n");
|
||||||
|
ret = AVERROR(EINVAL);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = execute_model_th(request, th_model->lltask_queue);
|
||||||
|
*output_width = task.out_frame->width;
|
||||||
|
*output_height = task.out_frame->height;
|
||||||
|
|
||||||
|
err:
|
||||||
|
av_frame_free(&task.out_frame);
|
||||||
|
av_frame_free(&task.in_frame);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static THInferRequest *th_create_inference_request(void)
|
||||||
|
{
|
||||||
|
THInferRequest *request = (THInferRequest *)av_malloc(sizeof(THInferRequest));
|
||||||
|
if (!request) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
request->input_tensor = NULL;
|
||||||
|
request->output = NULL;
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DNNModel *dnn_load_model_th(const char *model_filename, DNNFunctionType func_type, const char *options, AVFilterContext *filter_ctx)
|
||||||
|
{
|
||||||
|
DNNModel *model = NULL;
|
||||||
|
THModel *th_model = NULL;
|
||||||
|
THRequestItem *item = NULL;
|
||||||
|
THContext *ctx;
|
||||||
|
|
||||||
|
model = (DNNModel *)av_mallocz(sizeof(DNNModel));
|
||||||
|
if (!model) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
th_model = (THModel *)av_mallocz(sizeof(THModel));
|
||||||
|
if (!th_model) {
|
||||||
|
av_freep(&model);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
th_model->model = model;
|
||||||
|
model->model = th_model;
|
||||||
|
th_model->ctx.c_class = &dnn_th_class;
|
||||||
|
ctx = &th_model->ctx;
|
||||||
|
//parse options
|
||||||
|
av_opt_set_defaults(ctx);
|
||||||
|
if (av_opt_set_from_string(ctx, options, NULL, "=", "&") < 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to parse options \"%s\"\n", options);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
c10::Device device = c10::Device(ctx->options.device_name);
|
||||||
|
if (!device.is_cpu()) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Not supported device:\"%s\"\n", ctx->options.device_name);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
th_model->jit_model = new torch::jit::Module;
|
||||||
|
(*th_model->jit_model) = torch::jit::load(model_filename);
|
||||||
|
} catch (const c10::Error& e) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Failed to load torch model\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
th_model->request_queue = ff_safe_queue_create();
|
||||||
|
if (!th_model->request_queue) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
item = (THRequestItem *)av_mallocz(sizeof(THRequestItem));
|
||||||
|
if (!item) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
item->lltask = NULL;
|
||||||
|
item->infer_request = th_create_inference_request();
|
||||||
|
if (!item->infer_request) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "Failed to allocate memory for Torch inference request\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
item->exec_module.start_inference = &th_start_inference;
|
||||||
|
item->exec_module.callback = &infer_completion_callback;
|
||||||
|
item->exec_module.args = item;
|
||||||
|
|
||||||
|
if (ff_safe_queue_push_back(th_model->request_queue, item) < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
item = NULL;
|
||||||
|
|
||||||
|
th_model->task_queue = ff_queue_create();
|
||||||
|
if (!th_model->task_queue) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
th_model->lltask_queue = ff_queue_create();
|
||||||
|
if (!th_model->lltask_queue) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
model->get_input = &get_input_th;
|
||||||
|
model->get_output = &get_output_th;
|
||||||
|
model->options = NULL;
|
||||||
|
model->filter_ctx = filter_ctx;
|
||||||
|
model->func_type = func_type;
|
||||||
|
return model;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (item) {
|
||||||
|
destroy_request_item(&item);
|
||||||
|
av_freep(&item);
|
||||||
|
}
|
||||||
|
dnn_free_model_th(&model);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dnn_execute_model_th(const DNNModel *model, DNNExecBaseParams *exec_params)
|
||||||
|
{
|
||||||
|
THModel *th_model = (THModel *)model->model;
|
||||||
|
THContext *ctx = &th_model->ctx;
|
||||||
|
TaskItem *task;
|
||||||
|
THRequestItem *request;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = ff_check_exec_params(ctx, DNN_TH, model->func_type, exec_params);
|
||||||
|
if (ret != 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "exec parameter checking fail.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
task = (TaskItem *)av_malloc(sizeof(TaskItem));
|
||||||
|
if (!task) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to alloc memory for task item.\n");
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ff_dnn_fill_task(task, exec_params, th_model, 0, 1);
|
||||||
|
if (ret != 0) {
|
||||||
|
av_freep(&task);
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to fill task.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ff_queue_push_back(th_model->task_queue, task);
|
||||||
|
if (ret < 0) {
|
||||||
|
av_freep(&task);
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to push back task_queue.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = extract_lltask_from_task(task, th_model->lltask_queue);
|
||||||
|
if (ret != 0) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to extract last level task from task.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = (THRequestItem *)ff_safe_queue_pop_front(th_model->request_queue);
|
||||||
|
if (!request) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "unable to get infer request.\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return execute_model_th(request, th_model->lltask_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DNNAsyncStatusType dnn_get_result_th(const DNNModel *model, AVFrame **in, AVFrame **out)
|
||||||
|
{
|
||||||
|
THModel *th_model = (THModel *)model->model;
|
||||||
|
return ff_dnn_get_result_common(th_model->task_queue, in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dnn_flush_th(const DNNModel *model)
|
||||||
|
{
|
||||||
|
THModel *th_model = (THModel *)model->model;
|
||||||
|
THRequestItem *request;
|
||||||
|
|
||||||
|
if (ff_queue_size(th_model->lltask_queue) == 0)
|
||||||
|
// no pending task need to flush
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
request = (THRequestItem *)ff_safe_queue_pop_front(th_model->request_queue);
|
||||||
|
if (!request) {
|
||||||
|
av_log(&th_model->ctx, AV_LOG_ERROR, "unable to get infer request.\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return execute_model_th(request, th_model->lltask_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const DNNModule ff_dnn_backend_torch = {
|
||||||
|
.load_model = dnn_load_model_th,
|
||||||
|
.execute_model = dnn_execute_model_th,
|
||||||
|
.get_result = dnn_get_result_th,
|
||||||
|
.flush = dnn_flush_th,
|
||||||
|
.free_model = dnn_free_model_th,
|
||||||
|
};
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
extern const DNNModule ff_dnn_backend_openvino;
|
extern const DNNModule ff_dnn_backend_openvino;
|
||||||
extern const DNNModule ff_dnn_backend_tf;
|
extern const DNNModule ff_dnn_backend_tf;
|
||||||
|
extern const DNNModule ff_dnn_backend_torch;
|
||||||
|
|
||||||
const DNNModule *ff_get_dnn_module(DNNBackendType backend_type, void *log_ctx)
|
const DNNModule *ff_get_dnn_module(DNNBackendType backend_type, void *log_ctx)
|
||||||
{
|
{
|
||||||
|
@ -40,6 +41,10 @@ const DNNModule *ff_get_dnn_module(DNNBackendType backend_type, void *log_ctx)
|
||||||
case DNN_OV:
|
case DNN_OV:
|
||||||
return &ff_dnn_backend_openvino;
|
return &ff_dnn_backend_openvino;
|
||||||
#endif
|
#endif
|
||||||
|
#if (CONFIG_LIBTORCH == 1)
|
||||||
|
case DNN_TH:
|
||||||
|
return &ff_dnn_backend_torch;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
av_log(log_ctx, AV_LOG_ERROR,
|
av_log(log_ctx, AV_LOG_ERROR,
|
||||||
"Module backend_type %d is not supported or enabled.\n",
|
"Module backend_type %d is not supported or enabled.\n",
|
||||||
|
|
|
@ -53,12 +53,22 @@ static char **separate_output_names(const char *expr, const char *val_sep, int *
|
||||||
|
|
||||||
int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx)
|
int ff_dnn_init(DnnContext *ctx, DNNFunctionType func_type, AVFilterContext *filter_ctx)
|
||||||
{
|
{
|
||||||
|
DNNBackendType backend = ctx->backend_type;
|
||||||
|
|
||||||
if (!ctx->model_filename) {
|
if (!ctx->model_filename) {
|
||||||
av_log(filter_ctx, AV_LOG_ERROR, "model file for network is not specified\n");
|
av_log(filter_ctx, AV_LOG_ERROR, "model file for network is not specified\n");
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->backend_type == DNN_TF) {
|
if (backend == DNN_TH) {
|
||||||
|
if (ctx->model_inputname)
|
||||||
|
av_log(filter_ctx, AV_LOG_WARNING, "LibTorch backend do not require inputname, "\
|
||||||
|
"inputname will be ignored.\n");
|
||||||
|
if (ctx->model_outputnames)
|
||||||
|
av_log(filter_ctx, AV_LOG_WARNING, "LibTorch backend do not require outputname(s), "\
|
||||||
|
"all outputname(s) will be ignored.\n");
|
||||||
|
ctx->nb_outputs = 1;
|
||||||
|
} else if (backend == DNN_TF) {
|
||||||
if (!ctx->model_inputname) {
|
if (!ctx->model_inputname) {
|
||||||
av_log(filter_ctx, AV_LOG_ERROR, "input name of the model network is not specified\n");
|
av_log(filter_ctx, AV_LOG_ERROR, "input name of the model network is not specified\n");
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
|
@ -115,7 +125,8 @@ int ff_dnn_get_input(DnnContext *ctx, DNNData *input)
|
||||||
|
|
||||||
int ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height)
|
int ff_dnn_get_output(DnnContext *ctx, int input_width, int input_height, int *output_width, int *output_height)
|
||||||
{
|
{
|
||||||
char * output_name = ctx->model_outputnames ? ctx->model_outputnames[0] : NULL;
|
char * output_name = ctx->model_outputnames && ctx->backend_type != DNN_TH ?
|
||||||
|
ctx->model_outputnames[0] : NULL;
|
||||||
return ctx->model->get_output(ctx->model->model, ctx->model_inputname, input_width, input_height,
|
return ctx->model->get_output(ctx->model->model, ctx->model_inputname, input_width, input_height,
|
||||||
(const char *)output_name, output_width, output_height);
|
(const char *)output_name, output_width, output_height);
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue