xref: /rockchip-linux_mpp/mpp/codec/enc/h264/h264e_sps.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2015 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "h264e_sps"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_common.h"
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_enc_ref.h"
24*437bfbebSnyanmisaka #include "mpp_bitwrite.h"
25*437bfbebSnyanmisaka #include "h264e_debug.h"
26*437bfbebSnyanmisaka #include "h264e_sps.h"
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka typedef struct H264eLevelInfo_t {
29*437bfbebSnyanmisaka     H264Level       level;
30*437bfbebSnyanmisaka     RK_S32          max_MBPS;       /* Max macroblock rate per second */
31*437bfbebSnyanmisaka     RK_S32          max_MBs;        /* Max frame size */
32*437bfbebSnyanmisaka     RK_S32          max_DpbMBs;     /* Max decoded picture buffer size */
33*437bfbebSnyanmisaka     RK_S32          max_BR;         /* Max video bitrate */
34*437bfbebSnyanmisaka     const char      *name;
35*437bfbebSnyanmisaka } H264eLevelInfo;
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka H264eLevelInfo level_infos[] = {
38*437bfbebSnyanmisaka     /*  level             max_MBs  max_MBPS  max_DpbMBs  max_BR  name  */
39*437bfbebSnyanmisaka     {   H264_LEVEL_1_0,     1485,       99,        396,      64, "1"   },
40*437bfbebSnyanmisaka     {   H264_LEVEL_1_b,     1485,       99,        396,     128, "1.b" },
41*437bfbebSnyanmisaka     {   H264_LEVEL_1_1,     3000,      396,        900,     192, "1.1" },
42*437bfbebSnyanmisaka     {   H264_LEVEL_1_2,     6000,      396,       2376,     384, "1.2" },
43*437bfbebSnyanmisaka     {   H264_LEVEL_1_3,    11880,      396,       2376,     768, "1.3" },
44*437bfbebSnyanmisaka     {   H264_LEVEL_2_0,    11880,      396,       2376,    2000, "2"   },
45*437bfbebSnyanmisaka     {   H264_LEVEL_2_1,    19800,      792,       4752,    4000, "2.1" },
46*437bfbebSnyanmisaka     {   H264_LEVEL_2_2,    20250,     1620,       8100,    4000, "2.2" },
47*437bfbebSnyanmisaka     {   H264_LEVEL_3_0,    40500,     1620,       8100,   10000, "3"   },
48*437bfbebSnyanmisaka     {   H264_LEVEL_3_1,   108000,     3600,      18000,   14000, "3.1" },
49*437bfbebSnyanmisaka     {   H264_LEVEL_3_2,   216000,     5120,      20480,   20000, "3.2" },
50*437bfbebSnyanmisaka     {   H264_LEVEL_4_0,   245760,     8192,      32768,   20000, "4"   },
51*437bfbebSnyanmisaka     {   H264_LEVEL_4_1,   245760,     8192,      32768,   50000, "4.1" },
52*437bfbebSnyanmisaka     {   H264_LEVEL_4_2,   522240,     8704,      34816,   50000, "4.2" },
53*437bfbebSnyanmisaka     {   H264_LEVEL_5_0,   589824,    22080,     110400,  135000, "5"   },
54*437bfbebSnyanmisaka     {   H264_LEVEL_5_1,   983040,    36864,     184320,  240000, "5.1" },
55*437bfbebSnyanmisaka     {   H264_LEVEL_5_2,  2073600,    36864,     184320,  240000, "5.2" },
56*437bfbebSnyanmisaka     {   H264_LEVEL_6_0,  4177920,   139264,     696320,  240000, "6"   },
57*437bfbebSnyanmisaka     {   H264_LEVEL_6_1,  8355840,   139264,     696320,  480000, "6.1" },
58*437bfbebSnyanmisaka     {   H264_LEVEL_6_2, 16711680,   139264,     696320,  800000, "6.2" },
59*437bfbebSnyanmisaka };
60*437bfbebSnyanmisaka 
h264e_sps_update(H264eSps * sps,MppEncCfgSet * cfg)61*437bfbebSnyanmisaka MPP_RET h264e_sps_update(H264eSps *sps, MppEncCfgSet *cfg)
62*437bfbebSnyanmisaka {
63*437bfbebSnyanmisaka     H264eVui *vui = &sps->vui;
64*437bfbebSnyanmisaka     MppEncPrepCfg *prep = &cfg->prep;
65*437bfbebSnyanmisaka     MppEncRcCfg *rc = &cfg->rc;
66*437bfbebSnyanmisaka     MppEncH264Cfg *h264 = &cfg->h264;
67*437bfbebSnyanmisaka     MppEncRefCfg ref = cfg->ref_cfg;
68*437bfbebSnyanmisaka     MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref);
69*437bfbebSnyanmisaka     MppFrameFormat fmt = prep->format;
70*437bfbebSnyanmisaka     RK_S32 gop = rc->gop;
71*437bfbebSnyanmisaka     RK_S32 width = prep->width;
72*437bfbebSnyanmisaka     RK_S32 height = prep->height;
73*437bfbebSnyanmisaka     RK_S32 aligned_w = MPP_ALIGN(width, 16);
74*437bfbebSnyanmisaka     RK_S32 aligned_h = MPP_ALIGN(height, 16);
75*437bfbebSnyanmisaka     RK_S32 crop_right = MPP_ALIGN(width, 16) - width;
76*437bfbebSnyanmisaka     RK_S32 crop_bottom = MPP_ALIGN(height, 16) - height;
77*437bfbebSnyanmisaka     /* default 720p */
78*437bfbebSnyanmisaka     H264Level level_idc = h264->level;
79*437bfbebSnyanmisaka 
80*437bfbebSnyanmisaka     // default sps
81*437bfbebSnyanmisaka     // profile baseline
82*437bfbebSnyanmisaka     sps->profile_idc = h264->profile;
83*437bfbebSnyanmisaka     switch (sps->profile_idc) {
84*437bfbebSnyanmisaka     case H264_PROFILE_BASELINE : {
85*437bfbebSnyanmisaka         sps->constraint_set0 = 1;
86*437bfbebSnyanmisaka         sps->constraint_set1 = 1;
87*437bfbebSnyanmisaka         sps->constraint_set2 = 0;
88*437bfbebSnyanmisaka         sps->constraint_set3 = 0;
89*437bfbebSnyanmisaka         sps->constraint_set4 = 0;
90*437bfbebSnyanmisaka         sps->constraint_set5 = 0;
91*437bfbebSnyanmisaka     } break;
92*437bfbebSnyanmisaka     case H264_PROFILE_MAIN : {
93*437bfbebSnyanmisaka         sps->constraint_set0 = 0;
94*437bfbebSnyanmisaka         sps->constraint_set1 = 1;
95*437bfbebSnyanmisaka         sps->constraint_set2 = 0;
96*437bfbebSnyanmisaka         sps->constraint_set3 = 0;
97*437bfbebSnyanmisaka         sps->constraint_set4 = 0;
98*437bfbebSnyanmisaka         sps->constraint_set5 = 0;
99*437bfbebSnyanmisaka     } break;
100*437bfbebSnyanmisaka     case H264_PROFILE_HIGH :
101*437bfbebSnyanmisaka     case H264_PROFILE_HIGH10 :
102*437bfbebSnyanmisaka     case H264_PROFILE_HIGH422 :
103*437bfbebSnyanmisaka     case H264_PROFILE_HIGH444 : {
104*437bfbebSnyanmisaka         sps->constraint_set0 = 0;
105*437bfbebSnyanmisaka         sps->constraint_set1 = 0;
106*437bfbebSnyanmisaka         sps->constraint_set2 = 0;
107*437bfbebSnyanmisaka         sps->constraint_set3 = 0;
108*437bfbebSnyanmisaka         sps->constraint_set4 = 0;
109*437bfbebSnyanmisaka         sps->constraint_set5 = 0;
110*437bfbebSnyanmisaka     } break;
111*437bfbebSnyanmisaka     default : {
112*437bfbebSnyanmisaka         sps->constraint_set0 = 0;
113*437bfbebSnyanmisaka         sps->constraint_set1 = 0;
114*437bfbebSnyanmisaka         sps->constraint_set2 = 0;
115*437bfbebSnyanmisaka         sps->constraint_set3 = 0;
116*437bfbebSnyanmisaka         sps->constraint_set4 = 0;
117*437bfbebSnyanmisaka         sps->constraint_set5 = 0;
118*437bfbebSnyanmisaka     } break;
119*437bfbebSnyanmisaka     }
120*437bfbebSnyanmisaka 
121*437bfbebSnyanmisaka     //updata constraint_set0~5
122*437bfbebSnyanmisaka     RK_U32 set = h264->constraint_set;
123*437bfbebSnyanmisaka     RK_U8 constraint_force = (set >> 0) & 0x3f;
124*437bfbebSnyanmisaka     RK_U8 force_flag = (set >> 16) & 0x3f;
125*437bfbebSnyanmisaka 
126*437bfbebSnyanmisaka     if (force_flag & 1)
127*437bfbebSnyanmisaka         sps->constraint_set0 = (constraint_force & 1) ? 1 : 0;
128*437bfbebSnyanmisaka     if (force_flag & 2)
129*437bfbebSnyanmisaka         sps->constraint_set1 = (constraint_force & 2) ? 1 : 0;
130*437bfbebSnyanmisaka     if (force_flag & 4)
131*437bfbebSnyanmisaka         sps->constraint_set2 = (constraint_force & 4) ? 1 : 0;
132*437bfbebSnyanmisaka     if (force_flag & 8)
133*437bfbebSnyanmisaka         sps->constraint_set3 = (constraint_force & 8) ? 1 : 0;
134*437bfbebSnyanmisaka     if (force_flag & 16)
135*437bfbebSnyanmisaka         sps->constraint_set4 = (constraint_force & 16) ? 1 : 0;
136*437bfbebSnyanmisaka     if (force_flag & 32)
137*437bfbebSnyanmisaka         sps->constraint_set5 = (constraint_force & 32) ? 1 : 0;
138*437bfbebSnyanmisaka 
139*437bfbebSnyanmisaka     // level_idc is connected with frame size
140*437bfbebSnyanmisaka     {
141*437bfbebSnyanmisaka         RK_S32 mbs = (aligned_w * aligned_h) >> 8;
142*437bfbebSnyanmisaka         RK_S32 i;
143*437bfbebSnyanmisaka         RK_S32 min_level = 10;
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka         for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(level_infos); i++) {
146*437bfbebSnyanmisaka             if (level_infos[i].max_MBs >= mbs) {
147*437bfbebSnyanmisaka                 min_level = level_infos[i].level;
148*437bfbebSnyanmisaka 
149*437bfbebSnyanmisaka                 if (min_level > (RK_S32)level_idc &&
150*437bfbebSnyanmisaka                     min_level != H264_LEVEL_1_b) {
151*437bfbebSnyanmisaka                     level_idc = min_level;
152*437bfbebSnyanmisaka                     h264e_dbg_sps("set level to %s\n", level_infos[i].name);
153*437bfbebSnyanmisaka                 }
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka                 break;
156*437bfbebSnyanmisaka             }
157*437bfbebSnyanmisaka         }
158*437bfbebSnyanmisaka     }
159*437bfbebSnyanmisaka     sps->level_idc = level_idc;
160*437bfbebSnyanmisaka 
161*437bfbebSnyanmisaka     sps->sps_id = 0;
162*437bfbebSnyanmisaka     sps->chroma_format_idc = (fmt == MPP_FMT_YUV400) ? H264_CHROMA_400 : H264_CHROMA_420;
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka     // set max frame number and poc lsb according to gop size
165*437bfbebSnyanmisaka     sps->pic_order_cnt_type = h264->hw_cfg.hw_poc_type;
166*437bfbebSnyanmisaka     sps->log2_max_poc_lsb_minus4 = h264->log2_max_poc_lsb;
167*437bfbebSnyanmisaka     sps->log2_max_frame_num_minus4 = h264->log2_max_frame_num;
168*437bfbebSnyanmisaka 
169*437bfbebSnyanmisaka     mpp_assert(gop >= 0);
170*437bfbebSnyanmisaka     if (gop == 0) {
171*437bfbebSnyanmisaka         // only one I then all P frame
172*437bfbebSnyanmisaka         sps->log2_max_frame_num_minus4 = 12;
173*437bfbebSnyanmisaka         sps->log2_max_poc_lsb_minus4 = 12;
174*437bfbebSnyanmisaka     } else if (gop == 1) {
175*437bfbebSnyanmisaka         // all I frame
176*437bfbebSnyanmisaka         sps->log2_max_frame_num_minus4 = 12;
177*437bfbebSnyanmisaka         sps->log2_max_poc_lsb_minus4 = 12;
178*437bfbebSnyanmisaka     } else {
179*437bfbebSnyanmisaka         // normal case
180*437bfbebSnyanmisaka         RK_S32 log2_gop = MPP_MIN(mpp_log2(gop), 16);
181*437bfbebSnyanmisaka         RK_S32 log2_frm_num = (log2_gop <= 4) ? (0) : (log2_gop - 4);
182*437bfbebSnyanmisaka         RK_S32 log2_poc_lsb = (log2_gop <= 3) ? (0) : (log2_gop - 3);
183*437bfbebSnyanmisaka 
184*437bfbebSnyanmisaka         if (sps->log2_max_frame_num_minus4 < log2_frm_num)
185*437bfbebSnyanmisaka             sps->log2_max_frame_num_minus4 = log2_frm_num;
186*437bfbebSnyanmisaka 
187*437bfbebSnyanmisaka         if (log2_poc_lsb > 12)
188*437bfbebSnyanmisaka             log2_poc_lsb = 12;
189*437bfbebSnyanmisaka 
190*437bfbebSnyanmisaka         if (sps->log2_max_poc_lsb_minus4 < log2_poc_lsb)
191*437bfbebSnyanmisaka             sps->log2_max_poc_lsb_minus4 = log2_poc_lsb;
192*437bfbebSnyanmisaka     }
193*437bfbebSnyanmisaka 
194*437bfbebSnyanmisaka     // max one reference frame
195*437bfbebSnyanmisaka     sps->num_ref_frames = info->dpb_size;
196*437bfbebSnyanmisaka 
197*437bfbebSnyanmisaka     sps->gaps_in_frame_num_value_allowed = !h264->gaps_not_allowed;
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka     // default 720p without cropping
200*437bfbebSnyanmisaka     sps->pic_width_in_mbs = aligned_w >> 4;
201*437bfbebSnyanmisaka     sps->pic_height_in_mbs = aligned_h >> 4;
202*437bfbebSnyanmisaka     sps->frame_mbs_only = 1;
203*437bfbebSnyanmisaka 
204*437bfbebSnyanmisaka     // baseline disable 8x8
205*437bfbebSnyanmisaka     sps->direct8x8_inference = h264->transform8x8_mode;
206*437bfbebSnyanmisaka     if (crop_right || crop_bottom) {
207*437bfbebSnyanmisaka         sps->cropping = 1;
208*437bfbebSnyanmisaka         sps->crop.left = 0;
209*437bfbebSnyanmisaka         sps->crop.right = crop_right;
210*437bfbebSnyanmisaka         sps->crop.top = 0;
211*437bfbebSnyanmisaka         sps->crop.bottom = crop_bottom;
212*437bfbebSnyanmisaka     } else {
213*437bfbebSnyanmisaka         sps->cropping = 0;
214*437bfbebSnyanmisaka         memset(&sps->crop, 0, sizeof(sps->crop));
215*437bfbebSnyanmisaka     }
216*437bfbebSnyanmisaka 
217*437bfbebSnyanmisaka     memset(vui, 0, sizeof(*vui));
218*437bfbebSnyanmisaka     vui->vui_en = h264->vui.vui_en;
219*437bfbebSnyanmisaka     vui->timing_info_present = 1;
220*437bfbebSnyanmisaka     vui->time_scale = rc->fps_out_num * 2;
221*437bfbebSnyanmisaka     vui->num_units_in_tick = rc->fps_out_denom;
222*437bfbebSnyanmisaka     vui->fixed_frame_rate = !rc->fps_out_flex;
223*437bfbebSnyanmisaka     vui->vidformat = MPP_FRAME_VIDEO_FMT_UNSPECIFIED;
224*437bfbebSnyanmisaka 
225*437bfbebSnyanmisaka     if (prep->range == MPP_FRAME_RANGE_JPEG) {
226*437bfbebSnyanmisaka         vui->signal_type_present = 1;
227*437bfbebSnyanmisaka         vui->fullrange = 1;
228*437bfbebSnyanmisaka     }
229*437bfbebSnyanmisaka 
230*437bfbebSnyanmisaka     if ((prep->colorprim <= MPP_FRAME_PRI_JEDEC_P22 &&
231*437bfbebSnyanmisaka          prep->colorprim != MPP_FRAME_PRI_UNSPECIFIED) ||
232*437bfbebSnyanmisaka         (prep->colortrc <= MPP_FRAME_TRC_ARIB_STD_B67 &&
233*437bfbebSnyanmisaka          prep->colortrc != MPP_FRAME_TRC_UNSPECIFIED) ||
234*437bfbebSnyanmisaka         (prep->color <= MPP_FRAME_SPC_ICTCP &&
235*437bfbebSnyanmisaka          prep->color != MPP_FRAME_SPC_UNSPECIFIED)) {
236*437bfbebSnyanmisaka         vui->signal_type_present = 1;
237*437bfbebSnyanmisaka         vui->color_description_present = 1;
238*437bfbebSnyanmisaka         vui->colorprim = prep->colorprim;
239*437bfbebSnyanmisaka         vui->colortrc = prep->colortrc;
240*437bfbebSnyanmisaka         vui->colmatrix = prep->color;
241*437bfbebSnyanmisaka     }
242*437bfbebSnyanmisaka 
243*437bfbebSnyanmisaka     vui->bitstream_restriction = 1;
244*437bfbebSnyanmisaka     vui->motion_vectors_over_pic_boundaries = 1;
245*437bfbebSnyanmisaka     /* the max and default value has been changed to 15 since the 2016 standard */
246*437bfbebSnyanmisaka     vui->log2_max_mv_length_horizontal = 15;
247*437bfbebSnyanmisaka     vui->log2_max_mv_length_vertical = 15;
248*437bfbebSnyanmisaka     vui->max_dec_frame_buffering = info->dpb_size;
249*437bfbebSnyanmisaka 
250*437bfbebSnyanmisaka     return MPP_OK;
251*437bfbebSnyanmisaka }
252*437bfbebSnyanmisaka 
h264e_sps_to_packet(H264eSps * sps,MppPacket packet,RK_S32 * offset,RK_S32 * len,MppEncCfgSet * cfg)253*437bfbebSnyanmisaka MPP_RET h264e_sps_to_packet(H264eSps *sps, MppPacket packet, RK_S32 *offset,
254*437bfbebSnyanmisaka                             RK_S32 *len, MppEncCfgSet *cfg)
255*437bfbebSnyanmisaka {
256*437bfbebSnyanmisaka     void *pos = mpp_packet_get_pos(packet);
257*437bfbebSnyanmisaka     void *data = mpp_packet_get_data(packet);
258*437bfbebSnyanmisaka     size_t size = mpp_packet_get_size(packet);
259*437bfbebSnyanmisaka     size_t length = mpp_packet_get_length(packet);
260*437bfbebSnyanmisaka     void *p = pos + length;
261*437bfbebSnyanmisaka     RK_S32 buf_size = (data + size) - (pos + length);
262*437bfbebSnyanmisaka     MppWriteCtx bit_ctx;
263*437bfbebSnyanmisaka     MppWriteCtx *bit = &bit_ctx;
264*437bfbebSnyanmisaka     RK_S32 sps_size = 0;
265*437bfbebSnyanmisaka     static const RK_U32 SubWidthC[4]  = { 1, 2, 2, 1};
266*437bfbebSnyanmisaka     static const RK_U32 SubHeightC[4] = { 1, 2, 1, 1};
267*437bfbebSnyanmisaka 
268*437bfbebSnyanmisaka     mpp_writer_init(bit, p, buf_size);
269*437bfbebSnyanmisaka 
270*437bfbebSnyanmisaka     /* start_code_prefix 00 00 00 01 */
271*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 0, 24);
272*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 1, 8);
273*437bfbebSnyanmisaka     /* forbidden_zero_bit */
274*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, 0, 1);
275*437bfbebSnyanmisaka     /* nal_ref_idc */
276*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, H264_NALU_PRIORITY_HIGHEST, 2);
277*437bfbebSnyanmisaka     /* nal_unit_type */
278*437bfbebSnyanmisaka     mpp_writer_put_raw_bits(bit, H264_NALU_TYPE_SPS, 5);
279*437bfbebSnyanmisaka 
280*437bfbebSnyanmisaka     /* profile_idc */
281*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->profile_idc, 8);
282*437bfbebSnyanmisaka     /* constraint_set0_flag */
283*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->constraint_set0, 1);
284*437bfbebSnyanmisaka     /* constraint_set1_flag */
285*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->constraint_set1, 1);
286*437bfbebSnyanmisaka     /* constraint_set2_flag */
287*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->constraint_set2, 1);
288*437bfbebSnyanmisaka     /* constraint_set3_flag */
289*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->constraint_set3, 1);
290*437bfbebSnyanmisaka     /* constraint_set4_flag */
291*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->constraint_set4, 1);
292*437bfbebSnyanmisaka     /* constraint_set5_flag */
293*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->constraint_set5, 1);
294*437bfbebSnyanmisaka     /* reserved_zero_2bits */
295*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, 0, 2);
296*437bfbebSnyanmisaka 
297*437bfbebSnyanmisaka     /* level_idc */
298*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->level_idc, 8);
299*437bfbebSnyanmisaka     /* seq_parameter_set_id */
300*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, sps->sps_id);
301*437bfbebSnyanmisaka 
302*437bfbebSnyanmisaka     if (sps->profile_idc >= H264_PROFILE_HIGH) {
303*437bfbebSnyanmisaka         /* chroma_format_idc */
304*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, sps->chroma_format_idc);
305*437bfbebSnyanmisaka         /* bit_depth_luma_minus8 */
306*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, 0);
307*437bfbebSnyanmisaka         /* bit_depth_chroma_minus8 */
308*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, 0);
309*437bfbebSnyanmisaka         /* qpprime_y_zero_transform_bypass_flag */
310*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, 0, 1);
311*437bfbebSnyanmisaka         /* seq_scaling_matrix_present_flag */
312*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, 0, 1);
313*437bfbebSnyanmisaka     }
314*437bfbebSnyanmisaka 
315*437bfbebSnyanmisaka     /* log2_max_frame_num_minus4 */
316*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, sps->log2_max_frame_num_minus4);
317*437bfbebSnyanmisaka     /* pic_order_cnt_type */
318*437bfbebSnyanmisaka     /* accodring usr cfg cfg->h264.poc_type, hw may no support
319*437bfbebSnyanmisaka        will convert after get stream
320*437bfbebSnyanmisaka     */
321*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, cfg->h264.poc_type);
322*437bfbebSnyanmisaka     if (cfg->h264.poc_type == 0) {
323*437bfbebSnyanmisaka         /* log2_max_pic_order_cnt_lsb_minus4 */
324*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, sps->log2_max_poc_lsb_minus4);
325*437bfbebSnyanmisaka     }
326*437bfbebSnyanmisaka 
327*437bfbebSnyanmisaka     /* max_num_ref_frames */
328*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, sps->num_ref_frames);
329*437bfbebSnyanmisaka     /* gaps_in_frame_num_value_allowed_flag */
330*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->gaps_in_frame_num_value_allowed, 1);
331*437bfbebSnyanmisaka 
332*437bfbebSnyanmisaka     /* pic_width_in_mbs_minus1 */
333*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, sps->pic_width_in_mbs - 1);
334*437bfbebSnyanmisaka     /* pic_height_in_map_units_minus1 */
335*437bfbebSnyanmisaka     mpp_writer_put_ue(bit, sps->pic_height_in_mbs - 1);
336*437bfbebSnyanmisaka 
337*437bfbebSnyanmisaka     /* frame_mbs_only_flag */
338*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->frame_mbs_only, 1);
339*437bfbebSnyanmisaka     /* direct_8x8_inference_flag */
340*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->direct8x8_inference, 1);
341*437bfbebSnyanmisaka     /* frame_cropping_flag */
342*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->cropping, 1);
343*437bfbebSnyanmisaka     if (sps->cropping) {
344*437bfbebSnyanmisaka         /* frame_crop_left_offset */
345*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, sps->crop.left / SubWidthC[sps->chroma_format_idc]);
346*437bfbebSnyanmisaka         /* frame_crop_right_offset */
347*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, sps->crop.right / SubWidthC[sps->chroma_format_idc]);
348*437bfbebSnyanmisaka         /* frame_crop_top_offset */
349*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, sps->crop.top / SubHeightC[sps->chroma_format_idc]);
350*437bfbebSnyanmisaka         /* frame_crop_bottom_offset */
351*437bfbebSnyanmisaka         mpp_writer_put_ue(bit, sps->crop.bottom / SubHeightC[sps->chroma_format_idc]);
352*437bfbebSnyanmisaka     }
353*437bfbebSnyanmisaka 
354*437bfbebSnyanmisaka     /* vui_parameters_present_flag */
355*437bfbebSnyanmisaka     mpp_writer_put_bits(bit, sps->vui.vui_en, 1);
356*437bfbebSnyanmisaka     if (sps->vui.vui_en) {
357*437bfbebSnyanmisaka         H264eVui *vui = &sps->vui;
358*437bfbebSnyanmisaka 
359*437bfbebSnyanmisaka         /* aspect_ratio_info_present_flag */
360*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->aspect_ratio_info_present, 1);
361*437bfbebSnyanmisaka         if (vui->aspect_ratio_info_present) {
362*437bfbebSnyanmisaka             /* aspect_ratio_idc */
363*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->aspect_ratio_idc, 8);
364*437bfbebSnyanmisaka             if (H264_EXTENDED_SAR == vui->aspect_ratio_idc) {
365*437bfbebSnyanmisaka                 /* sar_width */
366*437bfbebSnyanmisaka                 mpp_writer_put_bits(bit, vui->sar_width, 16);
367*437bfbebSnyanmisaka                 /* sar_height */
368*437bfbebSnyanmisaka                 mpp_writer_put_bits(bit, vui->sar_height, 16);
369*437bfbebSnyanmisaka             }
370*437bfbebSnyanmisaka         }
371*437bfbebSnyanmisaka 
372*437bfbebSnyanmisaka         /* overscan_info_present */
373*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->overscan_info_present, 1);
374*437bfbebSnyanmisaka         if (vui->overscan_info_present) {
375*437bfbebSnyanmisaka             /* overscan_appropriate_flag */
376*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->overscan_appropriate_flag, 1);
377*437bfbebSnyanmisaka         }
378*437bfbebSnyanmisaka 
379*437bfbebSnyanmisaka         /* video_signal_type_present_flag */
380*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->signal_type_present, 1);
381*437bfbebSnyanmisaka         if (vui->signal_type_present) {
382*437bfbebSnyanmisaka             /* video_format */
383*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->vidformat, 3);
384*437bfbebSnyanmisaka             /* video_full_range_flag */
385*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->fullrange, 1);
386*437bfbebSnyanmisaka             /* colour_description_present_flag */
387*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->color_description_present, 1);
388*437bfbebSnyanmisaka             if (vui->color_description_present) {
389*437bfbebSnyanmisaka                 /* colour_primaries */
390*437bfbebSnyanmisaka                 mpp_writer_put_bits(bit, vui->colorprim, 8);
391*437bfbebSnyanmisaka                 /* transfer_characteristics */
392*437bfbebSnyanmisaka                 mpp_writer_put_bits(bit, vui->colortrc, 8);
393*437bfbebSnyanmisaka                 /* matrix_coefficients */
394*437bfbebSnyanmisaka                 mpp_writer_put_bits(bit, vui->colmatrix, 8);
395*437bfbebSnyanmisaka             }
396*437bfbebSnyanmisaka         }
397*437bfbebSnyanmisaka 
398*437bfbebSnyanmisaka         /* chroma_loc_info_present_flag */
399*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->chroma_loc_info_present, 1);
400*437bfbebSnyanmisaka         if (vui->chroma_loc_info_present) {
401*437bfbebSnyanmisaka             /* chroma_sample_loc_type_top_field */
402*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->chroma_loc_top);
403*437bfbebSnyanmisaka             /* chroma_sample_loc_type_bottom_field */
404*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->chroma_loc_bottom);
405*437bfbebSnyanmisaka         }
406*437bfbebSnyanmisaka 
407*437bfbebSnyanmisaka         /* timing_info_present_flag */
408*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->timing_info_present, 1);
409*437bfbebSnyanmisaka         if (vui->timing_info_present) {
410*437bfbebSnyanmisaka             /* num_units_in_tick msb */
411*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->num_units_in_tick >> 16, 16);
412*437bfbebSnyanmisaka             /* num_units_in_tick lsb */
413*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->num_units_in_tick & 0xffff, 16);
414*437bfbebSnyanmisaka             /* time_scale msb */
415*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->time_scale >> 16, 16);
416*437bfbebSnyanmisaka             /* time_scale lsb */
417*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->time_scale & 0xffff, 16);
418*437bfbebSnyanmisaka             /* fixed_frame_rate_flag */
419*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->fixed_frame_rate, 1);
420*437bfbebSnyanmisaka         }
421*437bfbebSnyanmisaka 
422*437bfbebSnyanmisaka         /* nal_hrd_parameters_present_flag */
423*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->nal_hrd_parameters_present, 1);
424*437bfbebSnyanmisaka         /* vcl_hrd_parameters_present_flag */
425*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->vcl_hrd_parameters_present, 1);
426*437bfbebSnyanmisaka         /* pic_struct_present_flag */
427*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->pic_struct_present, 1);
428*437bfbebSnyanmisaka 
429*437bfbebSnyanmisaka         /* bit_stream_restriction_flag */
430*437bfbebSnyanmisaka         mpp_writer_put_bits(bit, vui->bitstream_restriction, 1);
431*437bfbebSnyanmisaka         if (vui->bitstream_restriction) {
432*437bfbebSnyanmisaka             /* motion_vectors_over_pic_boundaries */
433*437bfbebSnyanmisaka             mpp_writer_put_bits(bit, vui->motion_vectors_over_pic_boundaries, 1);
434*437bfbebSnyanmisaka             /* max_bytes_per_pic_denom */
435*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->max_bytes_per_pic_denom);
436*437bfbebSnyanmisaka             /* max_bits_per_mb_denom */
437*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->max_bits_per_mb_denom);
438*437bfbebSnyanmisaka             /* log2_mv_length_horizontal */
439*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->log2_max_mv_length_horizontal);
440*437bfbebSnyanmisaka             /* log2_mv_length_vertical */
441*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->log2_max_mv_length_vertical);
442*437bfbebSnyanmisaka             /* num_reorder_frames */
443*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->num_reorder_frames);
444*437bfbebSnyanmisaka             /* max_dec_frame_buffering */
445*437bfbebSnyanmisaka             mpp_writer_put_ue(bit, vui->max_dec_frame_buffering);
446*437bfbebSnyanmisaka         }
447*437bfbebSnyanmisaka     }
448*437bfbebSnyanmisaka 
449*437bfbebSnyanmisaka     mpp_writer_trailing(bit);
450*437bfbebSnyanmisaka 
451*437bfbebSnyanmisaka     sps_size = mpp_writer_bytes(bit);
452*437bfbebSnyanmisaka     if (len)
453*437bfbebSnyanmisaka         *len = sps_size;
454*437bfbebSnyanmisaka     if (offset)
455*437bfbebSnyanmisaka         *offset = length;
456*437bfbebSnyanmisaka 
457*437bfbebSnyanmisaka     mpp_packet_set_length(packet, length + sps_size);
458*437bfbebSnyanmisaka 
459*437bfbebSnyanmisaka     return MPP_OK;
460*437bfbebSnyanmisaka }
461*437bfbebSnyanmisaka 
h264e_sps_dump(H264eSps * sps)462*437bfbebSnyanmisaka MPP_RET h264e_sps_dump(H264eSps *sps)
463*437bfbebSnyanmisaka {
464*437bfbebSnyanmisaka     (void) sps;
465*437bfbebSnyanmisaka     return MPP_OK;
466*437bfbebSnyanmisaka }
467