xref: /rockchip-linux_mpp/mpp/codec/dec/h263/h263d_parser.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  *
3*437bfbebSnyanmisaka  * Copyright 2010 Rockchip Electronics Co. LTD
4*437bfbebSnyanmisaka  *
5*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
6*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
7*437bfbebSnyanmisaka  * You may obtain a copy of the License at
8*437bfbebSnyanmisaka  *
9*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
10*437bfbebSnyanmisaka  *
11*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
12*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
13*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
15*437bfbebSnyanmisaka  * limitations under the License.
16*437bfbebSnyanmisaka  */
17*437bfbebSnyanmisaka 
18*437bfbebSnyanmisaka #include <string.h>
19*437bfbebSnyanmisaka 
20*437bfbebSnyanmisaka #include "mpp_env.h"
21*437bfbebSnyanmisaka #include "mpp_mem.h"
22*437bfbebSnyanmisaka #include "mpp_debug.h"
23*437bfbebSnyanmisaka 
24*437bfbebSnyanmisaka #include "mpp_bitread.h"
25*437bfbebSnyanmisaka #include "h263d_parser.h"
26*437bfbebSnyanmisaka #include "h263d_syntax.h"
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka RK_U32 h263d_debug = 0;
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka #define h263d_dbg(flag, fmt, ...)   _mpp_dbg(h263d_debug, flag, fmt, ## __VA_ARGS__)
31*437bfbebSnyanmisaka #define h263d_dbg_f(flag, fmt, ...) _mpp_dbg_f(h263d_debug, flag, fmt, ## __VA_ARGS__)
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka #define h263d_dbg_func(fmt, ...)    h263d_dbg_f(H263D_DBG_FUNCTION, fmt, ## __VA_ARGS__)
34*437bfbebSnyanmisaka #define h263d_dbg_bit(fmt, ...)     h263d_dbg(H263D_DBG_BITS, fmt, ## __VA_ARGS__)
35*437bfbebSnyanmisaka #define h263d_dbg_status(fmt, ...)  h263d_dbg(H263D_DBG_STATUS, fmt, ## __VA_ARGS__)
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka #define H263_STARTCODE                      0x00000080      /* 17 zero and 1 one */
38*437bfbebSnyanmisaka #define H263_STARTCODE_MASK                 0x00FFFF80
39*437bfbebSnyanmisaka #define H263_GOB_ZERO                       0x00000000
40*437bfbebSnyanmisaka #define H263_GOB_ZERO_MASK                  0x0000007C
41*437bfbebSnyanmisaka 
42*437bfbebSnyanmisaka #define H263_SF_SQCIF                       1      /* 001 */
43*437bfbebSnyanmisaka #define H263_SF_QCIF                        2      /* 010 */
44*437bfbebSnyanmisaka #define H263_SF_CIF                         3      /* 011 */
45*437bfbebSnyanmisaka #define H263_SF_4CIF                        4      /* 100 */
46*437bfbebSnyanmisaka #define H263_SF_16CIF                       5      /* 101 */
47*437bfbebSnyanmisaka #define H263_SF_CUSTOM                      6      /* 110 */
48*437bfbebSnyanmisaka #define H263_EXTENDED_PTYPE                 7      /* 111 */
49*437bfbebSnyanmisaka #define H263_EXTENDED_PAR                   15     /* 1111 */
50*437bfbebSnyanmisaka 
51*437bfbebSnyanmisaka typedef struct H263Hdr_t {
52*437bfbebSnyanmisaka     H263VOPType  pict_type;
53*437bfbebSnyanmisaka     RK_S32  width;
54*437bfbebSnyanmisaka     RK_S32  height;
55*437bfbebSnyanmisaka     RK_U32  TR;
56*437bfbebSnyanmisaka     RK_U32  quant;
57*437bfbebSnyanmisaka 
58*437bfbebSnyanmisaka     // frame related parameter
59*437bfbebSnyanmisaka     RK_S64  pts;
60*437bfbebSnyanmisaka     RK_S32  slot_idx;
61*437bfbebSnyanmisaka     RK_U32  enqueued;
62*437bfbebSnyanmisaka     RK_U32  hdr_bits;
63*437bfbebSnyanmisaka } H263Hdr;
64*437bfbebSnyanmisaka 
65*437bfbebSnyanmisaka typedef struct {
66*437bfbebSnyanmisaka     // global paramter
67*437bfbebSnyanmisaka     MppBufSlots     frame_slots;
68*437bfbebSnyanmisaka     RK_U32          use_internal_pts;
69*437bfbebSnyanmisaka     RK_U32          found_i_vop;
70*437bfbebSnyanmisaka 
71*437bfbebSnyanmisaka     // frame size parameter
72*437bfbebSnyanmisaka     RK_S32          width;
73*437bfbebSnyanmisaka     RK_S32          height;
74*437bfbebSnyanmisaka     RK_S32          hor_stride;
75*437bfbebSnyanmisaka     RK_S32          ver_stride;
76*437bfbebSnyanmisaka     RK_U32          info_change;
77*437bfbebSnyanmisaka     RK_U32          eos;
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka     // spliter parameter
80*437bfbebSnyanmisaka     RK_S32          pos_frm_start;      // negtive - not found; non-negtive - position of frame start
81*437bfbebSnyanmisaka     RK_S32          pos_frm_end;        // negtive - not found; non-negtive - position of frame end
82*437bfbebSnyanmisaka 
83*437bfbebSnyanmisaka     // bit read context
84*437bfbebSnyanmisaka     BitReadCtx_t    *bit_ctx;
85*437bfbebSnyanmisaka 
86*437bfbebSnyanmisaka     // decoding parameter
87*437bfbebSnyanmisaka     H263Hdr         hdr_curr;
88*437bfbebSnyanmisaka     H263Hdr         hdr_ref0;
89*437bfbebSnyanmisaka 
90*437bfbebSnyanmisaka     // dpb/output information
91*437bfbebSnyanmisaka     RK_S32          output;
92*437bfbebSnyanmisaka     RK_S64          pts;
93*437bfbebSnyanmisaka     RK_S64          dts;
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     // syntax for hal
96*437bfbebSnyanmisaka     h263d_dxva2_picture_context_t *syntax;
97*437bfbebSnyanmisaka } H263dParserImpl;
98*437bfbebSnyanmisaka 
99*437bfbebSnyanmisaka static RK_U32 h263d_fmt_to_dimension[8][2] = {
100*437bfbebSnyanmisaka     {    0,    0 },       /* invalid */
101*437bfbebSnyanmisaka     {  128,   96 },       /* SQCIF   */
102*437bfbebSnyanmisaka     {  176,  144 },       /* QCIF    */
103*437bfbebSnyanmisaka     {  352,  288 },       /* CIF     */
104*437bfbebSnyanmisaka     {  704,  576 },       /* 4CIF    */
105*437bfbebSnyanmisaka     { 1408, 1152 },       /* 16CIF   */
106*437bfbebSnyanmisaka     {    0,    0 },       /* custorm */
107*437bfbebSnyanmisaka     {    0,    0 },       /* extend  */
108*437bfbebSnyanmisaka };
109*437bfbebSnyanmisaka 
h263d_fill_picture_parameters(const H263dParserImpl * p,DXVA_PicParams_H263 * pp)110*437bfbebSnyanmisaka static void h263d_fill_picture_parameters(const H263dParserImpl *p,
111*437bfbebSnyanmisaka                                           DXVA_PicParams_H263 *pp)
112*437bfbebSnyanmisaka {
113*437bfbebSnyanmisaka     const H263Hdr *hdr_curr = &p->hdr_curr;
114*437bfbebSnyanmisaka     const H263Hdr *hdr_ref0 = &p->hdr_ref0;
115*437bfbebSnyanmisaka 
116*437bfbebSnyanmisaka     pp->short_video_header = 1;
117*437bfbebSnyanmisaka     pp->vop_coding_type = hdr_curr->pict_type;
118*437bfbebSnyanmisaka     pp->vop_quant = hdr_curr->quant;
119*437bfbebSnyanmisaka     pp->wDecodedPictureIndex = hdr_curr->slot_idx;
120*437bfbebSnyanmisaka     pp->wForwardRefPictureIndex = hdr_ref0->slot_idx;
121*437bfbebSnyanmisaka     pp->vop_time_increment_resolution = 30000;
122*437bfbebSnyanmisaka     pp->vop_width = hdr_curr->width;
123*437bfbebSnyanmisaka     pp->vop_height = hdr_curr->height;
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     // Rockchip special data
126*437bfbebSnyanmisaka     pp->prev_coding_type = hdr_ref0->pict_type;
127*437bfbebSnyanmisaka     pp->header_bits = hdr_curr->hdr_bits;
128*437bfbebSnyanmisaka }
129*437bfbebSnyanmisaka 
h263_syntax_init(h263d_dxva2_picture_context_t * syntax)130*437bfbebSnyanmisaka static void h263_syntax_init(h263d_dxva2_picture_context_t *syntax)
131*437bfbebSnyanmisaka {
132*437bfbebSnyanmisaka     DXVA2_DecodeBufferDesc *data = &syntax->desc[0];
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka     //!< commit picture paramters
135*437bfbebSnyanmisaka     memset(data, 0, sizeof(*data));
136*437bfbebSnyanmisaka     data->CompressedBufferType = DXVA2_PictureParametersBufferType;
137*437bfbebSnyanmisaka     data->pvPVPState = (void *)&syntax->pp;
138*437bfbebSnyanmisaka     data->DataSize = sizeof(syntax->pp);
139*437bfbebSnyanmisaka     syntax->data[0] = data;
140*437bfbebSnyanmisaka 
141*437bfbebSnyanmisaka     //!< commit bitstream
142*437bfbebSnyanmisaka     data = &syntax->desc[1];
143*437bfbebSnyanmisaka     memset(data, 0, sizeof(*data));
144*437bfbebSnyanmisaka     data->CompressedBufferType = DXVA2_BitStreamDateBufferType;
145*437bfbebSnyanmisaka     syntax->data[1] = data;
146*437bfbebSnyanmisaka }
147*437bfbebSnyanmisaka 
h263_parse_picture_header(H263dParserImpl * p,BitReadCtx_t * gb)148*437bfbebSnyanmisaka static MPP_RET h263_parse_picture_header(H263dParserImpl *p, BitReadCtx_t *gb)
149*437bfbebSnyanmisaka {
150*437bfbebSnyanmisaka     RK_U32 val = 0;
151*437bfbebSnyanmisaka     H263Hdr *hdr_curr = &p->hdr_curr;
152*437bfbebSnyanmisaka     H263VOPType pict_type = H263_INVALID_VOP;
153*437bfbebSnyanmisaka 
154*437bfbebSnyanmisaka     /* start code */
155*437bfbebSnyanmisaka     READ_BITS(gb, 17, &val); /* start code */
156*437bfbebSnyanmisaka     mpp_assert(val == 1);
157*437bfbebSnyanmisaka 
158*437bfbebSnyanmisaka     /* gob */
159*437bfbebSnyanmisaka     READ_BITS(gb, 5, &val); /* gob */
160*437bfbebSnyanmisaka     mpp_assert(val == 0);
161*437bfbebSnyanmisaka 
162*437bfbebSnyanmisaka     /* time reference */
163*437bfbebSnyanmisaka     READ_BITS(gb, 8, &hdr_curr->TR);
164*437bfbebSnyanmisaka 
165*437bfbebSnyanmisaka     /* first 5 bit of PTYPE */
166*437bfbebSnyanmisaka     SKIP_BITS(gb, 5);
167*437bfbebSnyanmisaka 
168*437bfbebSnyanmisaka     /* source format */
169*437bfbebSnyanmisaka     READ_BITS(gb, 3, &val); /* source format */
170*437bfbebSnyanmisaka     hdr_curr->width  = h263d_fmt_to_dimension[val][0];
171*437bfbebSnyanmisaka     hdr_curr->height = h263d_fmt_to_dimension[val][1];
172*437bfbebSnyanmisaka     if (!hdr_curr->width && !hdr_curr->height) {
173*437bfbebSnyanmisaka         mpp_err_f("unsupport source format %d\n", val);
174*437bfbebSnyanmisaka         return MPP_NOK;
175*437bfbebSnyanmisaka     }
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka     /* picture coding type: 0 - INTRA, 1 - INTER */
178*437bfbebSnyanmisaka     READ_BITS(gb, 1, &val);
179*437bfbebSnyanmisaka     pict_type = val;
180*437bfbebSnyanmisaka 
181*437bfbebSnyanmisaka     /* last 4 bit for PTYPE: UMV, AP mode, PB frame */
182*437bfbebSnyanmisaka     READ_BITS(gb, 4, &val);
183*437bfbebSnyanmisaka     if (val) {
184*437bfbebSnyanmisaka         mpp_err_f("unsupport PTYPE mode %x\n", val);
185*437bfbebSnyanmisaka         return MPP_NOK;
186*437bfbebSnyanmisaka     }
187*437bfbebSnyanmisaka 
188*437bfbebSnyanmisaka     READ_BITS(gb, 5, &val);
189*437bfbebSnyanmisaka     hdr_curr->quant = val;
190*437bfbebSnyanmisaka 
191*437bfbebSnyanmisaka     SKIP_BITS(gb, 1);
192*437bfbebSnyanmisaka 
193*437bfbebSnyanmisaka     READ_BITS(gb, 1, &val);
194*437bfbebSnyanmisaka     while (val) {
195*437bfbebSnyanmisaka         SKIP_BITS(gb, 8);
196*437bfbebSnyanmisaka         READ_BITS(gb, 1, &val);
197*437bfbebSnyanmisaka     }
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka     if (!p->found_i_vop)
200*437bfbebSnyanmisaka         p->found_i_vop = (pict_type == H263_I_VOP);
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka     if (!p->found_i_vop)
203*437bfbebSnyanmisaka         return MPP_NOK;
204*437bfbebSnyanmisaka 
205*437bfbebSnyanmisaka     hdr_curr->hdr_bits = gb->used_bits;
206*437bfbebSnyanmisaka     hdr_curr->pict_type = pict_type;
207*437bfbebSnyanmisaka 
208*437bfbebSnyanmisaka     return MPP_OK;
209*437bfbebSnyanmisaka __BITREAD_ERR:
210*437bfbebSnyanmisaka     mpp_err_f("found error stream\n");
211*437bfbebSnyanmisaka     return MPP_ERR_STREAM;
212*437bfbebSnyanmisaka }
213*437bfbebSnyanmisaka 
mpp_h263_parser_init(H263dParser * ctx,MppBufSlots frame_slots)214*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_init(H263dParser *ctx, MppBufSlots frame_slots)
215*437bfbebSnyanmisaka {
216*437bfbebSnyanmisaka     BitReadCtx_t *bit_ctx = mpp_calloc(BitReadCtx_t, 1);
217*437bfbebSnyanmisaka     H263dParserImpl *p = mpp_calloc(H263dParserImpl, 1);
218*437bfbebSnyanmisaka     h263d_dxva2_picture_context_t *syntax = mpp_calloc(h263d_dxva2_picture_context_t, 1);
219*437bfbebSnyanmisaka 
220*437bfbebSnyanmisaka     if (NULL == p || NULL == bit_ctx || NULL == syntax) {
221*437bfbebSnyanmisaka         mpp_err_f("malloc context failed\n");
222*437bfbebSnyanmisaka         if (p)
223*437bfbebSnyanmisaka             mpp_free(p);
224*437bfbebSnyanmisaka         if (bit_ctx)
225*437bfbebSnyanmisaka             mpp_free(bit_ctx);
226*437bfbebSnyanmisaka         if (syntax)
227*437bfbebSnyanmisaka             mpp_free(syntax);
228*437bfbebSnyanmisaka         return MPP_NOK;
229*437bfbebSnyanmisaka     }
230*437bfbebSnyanmisaka 
231*437bfbebSnyanmisaka     mpp_buf_slot_setup(frame_slots, 4);
232*437bfbebSnyanmisaka     p->frame_slots      = frame_slots;
233*437bfbebSnyanmisaka     p->pos_frm_start    = -1;
234*437bfbebSnyanmisaka     p->pos_frm_end      = -1;
235*437bfbebSnyanmisaka     p->bit_ctx          = bit_ctx;
236*437bfbebSnyanmisaka     p->hdr_curr.slot_idx = H263_INVALID_VOP;
237*437bfbebSnyanmisaka     p->hdr_ref0.slot_idx = H263_INVALID_VOP;
238*437bfbebSnyanmisaka     h263_syntax_init(syntax);
239*437bfbebSnyanmisaka     p->syntax = syntax;
240*437bfbebSnyanmisaka 
241*437bfbebSnyanmisaka     mpp_env_get_u32("h263d_debug", &h263d_debug, 0);
242*437bfbebSnyanmisaka 
243*437bfbebSnyanmisaka     *ctx = p;
244*437bfbebSnyanmisaka     return MPP_OK;
245*437bfbebSnyanmisaka }
246*437bfbebSnyanmisaka 
mpp_h263_parser_deinit(H263dParser ctx)247*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_deinit(H263dParser ctx)
248*437bfbebSnyanmisaka {
249*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
250*437bfbebSnyanmisaka     if (p) {
251*437bfbebSnyanmisaka         if (p->bit_ctx) {
252*437bfbebSnyanmisaka             mpp_free(p->bit_ctx);
253*437bfbebSnyanmisaka             p->bit_ctx = NULL;
254*437bfbebSnyanmisaka         }
255*437bfbebSnyanmisaka         if (p->syntax) {
256*437bfbebSnyanmisaka             mpp_free(p->syntax);
257*437bfbebSnyanmisaka             p->syntax = NULL;
258*437bfbebSnyanmisaka         }
259*437bfbebSnyanmisaka         mpp_free(p);
260*437bfbebSnyanmisaka     }
261*437bfbebSnyanmisaka     return MPP_OK;
262*437bfbebSnyanmisaka }
263*437bfbebSnyanmisaka 
mpp_h263_parser_flush(H263dParser ctx)264*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_flush(H263dParser ctx)
265*437bfbebSnyanmisaka {
266*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
267*437bfbebSnyanmisaka     MppBufSlots slots = p->frame_slots;
268*437bfbebSnyanmisaka     H263Hdr *hdr_curr = &p->hdr_ref0;
269*437bfbebSnyanmisaka     RK_S32 index = hdr_curr->slot_idx;
270*437bfbebSnyanmisaka 
271*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
272*437bfbebSnyanmisaka 
273*437bfbebSnyanmisaka     if (!hdr_curr->enqueued && index >= 0) {
274*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE);
275*437bfbebSnyanmisaka         mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY);
276*437bfbebSnyanmisaka         hdr_curr->enqueued = 1;
277*437bfbebSnyanmisaka     }
278*437bfbebSnyanmisaka 
279*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
280*437bfbebSnyanmisaka 
281*437bfbebSnyanmisaka     return MPP_OK;
282*437bfbebSnyanmisaka }
283*437bfbebSnyanmisaka 
mpp_h263_parser_reset(H263dParser ctx)284*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_reset(H263dParser ctx)
285*437bfbebSnyanmisaka {
286*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
287*437bfbebSnyanmisaka     MppBufSlots slots = p->frame_slots;
288*437bfbebSnyanmisaka     H263Hdr *hdr_curr = &p->hdr_ref0;
289*437bfbebSnyanmisaka     H263Hdr *hdr_ref0 = &p->hdr_ref0;
290*437bfbebSnyanmisaka     RK_S32 index = hdr_curr->slot_idx;
291*437bfbebSnyanmisaka 
292*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
293*437bfbebSnyanmisaka 
294*437bfbebSnyanmisaka     if (index >= 0) {
295*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE);
296*437bfbebSnyanmisaka         hdr_curr->slot_idx = -1;
297*437bfbebSnyanmisaka     }
298*437bfbebSnyanmisaka 
299*437bfbebSnyanmisaka     index = hdr_ref0->slot_idx;
300*437bfbebSnyanmisaka     if (index >= 0) {
301*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE);
302*437bfbebSnyanmisaka         hdr_ref0->slot_idx = -1;
303*437bfbebSnyanmisaka     }
304*437bfbebSnyanmisaka 
305*437bfbebSnyanmisaka     p->found_i_vop = 0;
306*437bfbebSnyanmisaka 
307*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
308*437bfbebSnyanmisaka 
309*437bfbebSnyanmisaka     return MPP_OK;
310*437bfbebSnyanmisaka }
311*437bfbebSnyanmisaka 
mpp_h263_parser_split(H263dParser ctx,MppPacket dst,MppPacket src)312*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_split(H263dParser ctx, MppPacket dst, MppPacket src)
313*437bfbebSnyanmisaka {
314*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
315*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
316*437bfbebSnyanmisaka     RK_U8 *dst_buf = mpp_packet_get_data(dst);
317*437bfbebSnyanmisaka     size_t dst_len = mpp_packet_get_length(dst);
318*437bfbebSnyanmisaka     RK_U8 *src_buf = mpp_packet_get_pos(src);
319*437bfbebSnyanmisaka     RK_S32 src_len = (RK_S32)mpp_packet_get_length(src);
320*437bfbebSnyanmisaka     RK_S32 pos_frm_start = p->pos_frm_start;
321*437bfbebSnyanmisaka     RK_S32 pos_frm_end   = p->pos_frm_end;
322*437bfbebSnyanmisaka     RK_U32 src_eos = mpp_packet_get_eos(src);
323*437bfbebSnyanmisaka     RK_S32 src_pos = 0;
324*437bfbebSnyanmisaka     RK_U32 state = (RK_U32) - 1;
325*437bfbebSnyanmisaka 
326*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
327*437bfbebSnyanmisaka 
328*437bfbebSnyanmisaka     mpp_assert(src_len);
329*437bfbebSnyanmisaka 
330*437bfbebSnyanmisaka     if (dst_len) {
331*437bfbebSnyanmisaka         mpp_assert(dst_len >= 4);
332*437bfbebSnyanmisaka         state = ((RK_U32)(dst_buf[dst_len - 1]) <<  0) |
333*437bfbebSnyanmisaka                 ((RK_U32)(dst_buf[dst_len - 2]) <<  8) |
334*437bfbebSnyanmisaka                 ((RK_U32)(dst_buf[dst_len - 3]) << 16) |
335*437bfbebSnyanmisaka                 ((RK_U32)(dst_buf[dst_len - 4]) << 24);
336*437bfbebSnyanmisaka     }
337*437bfbebSnyanmisaka 
338*437bfbebSnyanmisaka     if (pos_frm_start < 0) {
339*437bfbebSnyanmisaka         // scan for frame start
340*437bfbebSnyanmisaka         for (src_pos = 0; src_pos < src_len; src_pos++) {
341*437bfbebSnyanmisaka             state = (state << 8) | src_buf[src_pos];
342*437bfbebSnyanmisaka             if ((state & H263_STARTCODE_MASK) == H263_STARTCODE &&
343*437bfbebSnyanmisaka                 (state & H263_GOB_ZERO_MASK)  == H263_GOB_ZERO) {
344*437bfbebSnyanmisaka                 pos_frm_start = src_pos - 2;
345*437bfbebSnyanmisaka                 src_pos++;
346*437bfbebSnyanmisaka                 break;
347*437bfbebSnyanmisaka             }
348*437bfbebSnyanmisaka         }
349*437bfbebSnyanmisaka     }
350*437bfbebSnyanmisaka 
351*437bfbebSnyanmisaka     if (pos_frm_start >= 0) {
352*437bfbebSnyanmisaka         // scan for frame end
353*437bfbebSnyanmisaka         for (; src_pos < src_len; src_pos++) {
354*437bfbebSnyanmisaka             state = (state << 8) | src_buf[src_pos];
355*437bfbebSnyanmisaka 
356*437bfbebSnyanmisaka             if ((state & H263_STARTCODE_MASK) == H263_STARTCODE &&
357*437bfbebSnyanmisaka                 (state & H263_GOB_ZERO_MASK)  == H263_GOB_ZERO) {
358*437bfbebSnyanmisaka                 pos_frm_end = src_pos - 2;
359*437bfbebSnyanmisaka                 break;
360*437bfbebSnyanmisaka             }
361*437bfbebSnyanmisaka         }
362*437bfbebSnyanmisaka         if (src_eos && src_pos == src_len) {
363*437bfbebSnyanmisaka             pos_frm_end = src_len;
364*437bfbebSnyanmisaka             mpp_packet_set_eos(dst);
365*437bfbebSnyanmisaka         }
366*437bfbebSnyanmisaka     }
367*437bfbebSnyanmisaka 
368*437bfbebSnyanmisaka     //mpp_log("pkt pos: start %d end %d len: left %d in %d\n",
369*437bfbebSnyanmisaka     //        pos_frm_start, pos_frm_end, dst_len, src_len);
370*437bfbebSnyanmisaka 
371*437bfbebSnyanmisaka     if (pos_frm_start < 0 || pos_frm_end < 0) {
372*437bfbebSnyanmisaka         // do not found frame start or do not found frame end, just copy the hold buffer to dst
373*437bfbebSnyanmisaka         memcpy(dst_buf + dst_len, src_buf, src_len);
374*437bfbebSnyanmisaka         // update dst buffer length
375*437bfbebSnyanmisaka         mpp_packet_set_length(dst, dst_len + src_len);
376*437bfbebSnyanmisaka         // set src buffer pos to end to src buffer
377*437bfbebSnyanmisaka         mpp_packet_set_pos(src, src_buf + src_len);
378*437bfbebSnyanmisaka     } else {
379*437bfbebSnyanmisaka         // found both frame start and frame end - only copy frame
380*437bfbebSnyanmisaka         memcpy(dst_buf + dst_len, src_buf, pos_frm_end);
381*437bfbebSnyanmisaka         mpp_packet_set_length(dst, dst_len + pos_frm_end);
382*437bfbebSnyanmisaka 
383*437bfbebSnyanmisaka         // set src buffer pos to end to src buffer
384*437bfbebSnyanmisaka         mpp_packet_set_pos(src, src_buf + pos_frm_end);
385*437bfbebSnyanmisaka         mpp_assert((RK_S32)mpp_packet_get_length(src) == (src_len - pos_frm_end));
386*437bfbebSnyanmisaka         mpp_packet_set_length(src, src_len - pos_frm_end);
387*437bfbebSnyanmisaka 
388*437bfbebSnyanmisaka         // return ok indicate the frame is ready and reset frame start/end position
389*437bfbebSnyanmisaka         ret = MPP_OK;
390*437bfbebSnyanmisaka         pos_frm_start = -1;
391*437bfbebSnyanmisaka         pos_frm_end = -1;
392*437bfbebSnyanmisaka     }
393*437bfbebSnyanmisaka 
394*437bfbebSnyanmisaka     p->pos_frm_start = pos_frm_start;
395*437bfbebSnyanmisaka     p->pos_frm_end   = pos_frm_end;
396*437bfbebSnyanmisaka 
397*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
398*437bfbebSnyanmisaka 
399*437bfbebSnyanmisaka     return ret;
400*437bfbebSnyanmisaka }
401*437bfbebSnyanmisaka 
mpp_h263_parser_decode(H263dParser ctx,MppPacket pkt)402*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_decode(H263dParser ctx, MppPacket pkt)
403*437bfbebSnyanmisaka {
404*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
405*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
406*437bfbebSnyanmisaka     BitReadCtx_t *gb = p->bit_ctx;
407*437bfbebSnyanmisaka     RK_U8 *buf = mpp_packet_get_data(pkt);
408*437bfbebSnyanmisaka     RK_S32 len = (RK_S32)mpp_packet_get_length(pkt);
409*437bfbebSnyanmisaka     RK_U32 startcode = 0xff;
410*437bfbebSnyanmisaka     RK_S32 i = 0;
411*437bfbebSnyanmisaka 
412*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
413*437bfbebSnyanmisaka 
414*437bfbebSnyanmisaka     while (i < len) {
415*437bfbebSnyanmisaka         startcode = (startcode << 8) | buf[i++];
416*437bfbebSnyanmisaka 
417*437bfbebSnyanmisaka         if (startcode >> (32 - 22) == 0x20) {
418*437bfbebSnyanmisaka             i -= 4;
419*437bfbebSnyanmisaka             h263d_dbg_bit("found startcode at byte %d\n", i);
420*437bfbebSnyanmisaka             break;
421*437bfbebSnyanmisaka         }
422*437bfbebSnyanmisaka     }
423*437bfbebSnyanmisaka 
424*437bfbebSnyanmisaka     if (i == len) {
425*437bfbebSnyanmisaka         mpp_err_f("can not found start code in len %d packet\n", len);
426*437bfbebSnyanmisaka         goto __BITREAD_ERR;
427*437bfbebSnyanmisaka     }
428*437bfbebSnyanmisaka 
429*437bfbebSnyanmisaka     // setup bit read context
430*437bfbebSnyanmisaka     mpp_set_bitread_ctx(gb, buf + i, len - i);
431*437bfbebSnyanmisaka 
432*437bfbebSnyanmisaka     ret = h263_parse_picture_header(p, gb);
433*437bfbebSnyanmisaka     if (ret)
434*437bfbebSnyanmisaka         goto __BITREAD_ERR;
435*437bfbebSnyanmisaka 
436*437bfbebSnyanmisaka     p->width  = p->hdr_curr.width;
437*437bfbebSnyanmisaka     p->height = p->hdr_curr.height;
438*437bfbebSnyanmisaka     p->pts  = mpp_packet_get_pts(pkt);
439*437bfbebSnyanmisaka     p->dts  = mpp_packet_get_dts(pkt);
440*437bfbebSnyanmisaka __BITREAD_ERR:
441*437bfbebSnyanmisaka     h263d_dbg_status("found i_frame %d frame_type %d ret %d\n",
442*437bfbebSnyanmisaka                      p->found_i_vop, p->hdr_curr.pict_type, ret);
443*437bfbebSnyanmisaka 
444*437bfbebSnyanmisaka     mpp_packet_set_pos(pkt, buf);
445*437bfbebSnyanmisaka     mpp_packet_set_length(pkt, 0);
446*437bfbebSnyanmisaka     p->eos = mpp_packet_get_eos(pkt);
447*437bfbebSnyanmisaka 
448*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
449*437bfbebSnyanmisaka 
450*437bfbebSnyanmisaka     return ret;
451*437bfbebSnyanmisaka }
452*437bfbebSnyanmisaka 
mpp_h263_parser_setup_syntax(H263dParser ctx,MppSyntax * syntax)453*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_setup_syntax(H263dParser ctx, MppSyntax *syntax)
454*437bfbebSnyanmisaka {
455*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
456*437bfbebSnyanmisaka     h263d_dxva2_picture_context_t *syn = p->syntax;
457*437bfbebSnyanmisaka 
458*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
459*437bfbebSnyanmisaka 
460*437bfbebSnyanmisaka     h263d_fill_picture_parameters(p, &syn->pp);
461*437bfbebSnyanmisaka 
462*437bfbebSnyanmisaka     // fill bit stream parameter
463*437bfbebSnyanmisaka     syn->data[1]->DataSize   = p->bit_ctx->buf_len;
464*437bfbebSnyanmisaka     syn->data[1]->DataOffset = p->hdr_curr.hdr_bits;
465*437bfbebSnyanmisaka     syn->data[1]->pvPVPState = p->bit_ctx->buf;
466*437bfbebSnyanmisaka 
467*437bfbebSnyanmisaka     syntax->number = 2;
468*437bfbebSnyanmisaka     syntax->data = syn->data;
469*437bfbebSnyanmisaka 
470*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
471*437bfbebSnyanmisaka 
472*437bfbebSnyanmisaka     return MPP_OK;
473*437bfbebSnyanmisaka }
474*437bfbebSnyanmisaka 
mpp_h263_parser_setup_hal_output(H263dParser ctx,RK_S32 * output)475*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_setup_hal_output(H263dParser ctx, RK_S32 *output)
476*437bfbebSnyanmisaka {
477*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
478*437bfbebSnyanmisaka     RK_S32 index = -1;
479*437bfbebSnyanmisaka 
480*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
481*437bfbebSnyanmisaka 
482*437bfbebSnyanmisaka     if (p->found_i_vop) {
483*437bfbebSnyanmisaka         H263Hdr *hdr_curr = &p->hdr_curr;
484*437bfbebSnyanmisaka         MppBufSlots slots = p->frame_slots;
485*437bfbebSnyanmisaka         MppFrame frame = NULL;
486*437bfbebSnyanmisaka 
487*437bfbebSnyanmisaka         mpp_frame_init(&frame);
488*437bfbebSnyanmisaka         mpp_frame_set_width(frame, p->width);
489*437bfbebSnyanmisaka         mpp_frame_set_height(frame, p->height);
490*437bfbebSnyanmisaka         mpp_frame_set_hor_stride(frame, MPP_ALIGN(p->width, 16));
491*437bfbebSnyanmisaka         mpp_frame_set_ver_stride(frame, MPP_ALIGN(p->height, 16));
492*437bfbebSnyanmisaka 
493*437bfbebSnyanmisaka         /*
494*437bfbebSnyanmisaka          * set slots information
495*437bfbebSnyanmisaka          * 1. output index MUST be set
496*437bfbebSnyanmisaka          * 2. get unused index for output if needed
497*437bfbebSnyanmisaka          * 3. set output index as hal_input
498*437bfbebSnyanmisaka          * 4. set frame information to output index
499*437bfbebSnyanmisaka          * 5. if one frame can be display, it SHOULD be enqueued to display queue
500*437bfbebSnyanmisaka          */
501*437bfbebSnyanmisaka         mpp_buf_slot_get_unused(slots, &index);
502*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(slots, index, SLOT_HAL_OUTPUT);
503*437bfbebSnyanmisaka         mpp_frame_set_pts(frame, p->pts);
504*437bfbebSnyanmisaka         mpp_frame_set_dts(frame, p->dts);
505*437bfbebSnyanmisaka         mpp_frame_set_mode(frame, MPP_FRAME_FLAG_FRAME);
506*437bfbebSnyanmisaka 
507*437bfbebSnyanmisaka         mpp_buf_slot_set_prop(slots, index, SLOT_FRAME, frame);
508*437bfbebSnyanmisaka         mpp_frame_deinit(&frame);
509*437bfbebSnyanmisaka         mpp_assert(NULL == frame);
510*437bfbebSnyanmisaka 
511*437bfbebSnyanmisaka         hdr_curr->slot_idx = index;
512*437bfbebSnyanmisaka     }
513*437bfbebSnyanmisaka 
514*437bfbebSnyanmisaka     p->output = index;
515*437bfbebSnyanmisaka     *output = index;
516*437bfbebSnyanmisaka 
517*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
518*437bfbebSnyanmisaka 
519*437bfbebSnyanmisaka     return MPP_OK;
520*437bfbebSnyanmisaka }
521*437bfbebSnyanmisaka 
mpp_h263_parser_setup_refer(H263dParser ctx,RK_S32 * refer,RK_S32 max_ref)522*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_setup_refer(H263dParser ctx, RK_S32 *refer, RK_S32 max_ref)
523*437bfbebSnyanmisaka {
524*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
525*437bfbebSnyanmisaka     H263Hdr *hdr_curr = &p->hdr_curr;
526*437bfbebSnyanmisaka     MppBufSlots slots = p->frame_slots;
527*437bfbebSnyanmisaka     RK_S32 index;
528*437bfbebSnyanmisaka 
529*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
530*437bfbebSnyanmisaka 
531*437bfbebSnyanmisaka     memset(refer, -1, sizeof(max_ref * sizeof(*refer)));
532*437bfbebSnyanmisaka     if (hdr_curr->pict_type == H263_P_VOP) {
533*437bfbebSnyanmisaka         index = p->hdr_ref0.slot_idx;
534*437bfbebSnyanmisaka         if (index >= 0) {
535*437bfbebSnyanmisaka             mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT);
536*437bfbebSnyanmisaka             refer[0] = index;
537*437bfbebSnyanmisaka         }
538*437bfbebSnyanmisaka     }
539*437bfbebSnyanmisaka 
540*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
541*437bfbebSnyanmisaka 
542*437bfbebSnyanmisaka     return MPP_OK;
543*437bfbebSnyanmisaka }
544*437bfbebSnyanmisaka 
mpp_h263_parser_update_dpb(H263dParser ctx)545*437bfbebSnyanmisaka MPP_RET mpp_h263_parser_update_dpb(H263dParser ctx)
546*437bfbebSnyanmisaka {
547*437bfbebSnyanmisaka     H263dParserImpl *p = (H263dParserImpl *)ctx;
548*437bfbebSnyanmisaka     MppBufSlots slots = p->frame_slots;
549*437bfbebSnyanmisaka     H263Hdr *hdr_curr = &p->hdr_curr;
550*437bfbebSnyanmisaka     H263Hdr *hdr_ref0 = &p->hdr_ref0;
551*437bfbebSnyanmisaka     RK_S32 index = hdr_curr->slot_idx;
552*437bfbebSnyanmisaka 
553*437bfbebSnyanmisaka     h263d_dbg_func("in\n");
554*437bfbebSnyanmisaka 
555*437bfbebSnyanmisaka     mpp_assert(index >= 0);
556*437bfbebSnyanmisaka     mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_USE);
557*437bfbebSnyanmisaka     mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE);
558*437bfbebSnyanmisaka     mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY);
559*437bfbebSnyanmisaka     hdr_curr->enqueued = 1;
560*437bfbebSnyanmisaka 
561*437bfbebSnyanmisaka     index = hdr_ref0->slot_idx;
562*437bfbebSnyanmisaka     if (index >= 0) {
563*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE);
564*437bfbebSnyanmisaka         hdr_ref0->slot_idx = -1;
565*437bfbebSnyanmisaka     }
566*437bfbebSnyanmisaka 
567*437bfbebSnyanmisaka     // swap current to ref0
568*437bfbebSnyanmisaka     *hdr_ref0 = *hdr_curr;
569*437bfbebSnyanmisaka     hdr_curr->slot_idx  = H263_INVALID_VOP;
570*437bfbebSnyanmisaka     hdr_curr->pts       = 0;
571*437bfbebSnyanmisaka     hdr_curr->enqueued  = 0;
572*437bfbebSnyanmisaka 
573*437bfbebSnyanmisaka     h263d_dbg_func("out\n");
574*437bfbebSnyanmisaka 
575*437bfbebSnyanmisaka     return MPP_OK;
576*437bfbebSnyanmisaka }
577*437bfbebSnyanmisaka 
578*437bfbebSnyanmisaka 
579*437bfbebSnyanmisaka 
580