xref: /rockchip-linux_mpp/mpp/codec/dec/vp8/vp8d_parser.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  *
3  * Copyright 2015 Rockchip Electronics Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #define MODULE_TAG "vp8d_parser"
18 
19 #include <string.h>
20 #include <unistd.h>
21 
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_debug.h"
25 #include "mpp_frame.h"
26 
27 #include "vp8d_parser.h"
28 #include "vp8d_codec.h"
29 
30 #define FUN_T(tag) \
31     do {\
32         if (VP8D_DBG_FUNCTION & vp8d_debug)\
33             { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\
34     } while (0)
35 
36 static RK_U32 vp8d_debug = 0x0;
37 
vp8hwdBoolStart(vpBoolCoder_t * bit_ctx,RK_U8 * buffer,RK_U32 len)38 static void vp8hwdBoolStart(vpBoolCoder_t *bit_ctx, RK_U8 *buffer, RK_U32 len)
39 {
40     FUN_T("FUN_IN");
41     bit_ctx->lowvalue = 0;
42     bit_ctx->range = 255;
43     bit_ctx->count = 8;
44     bit_ctx->buffer = buffer;
45     bit_ctx->pos = 0;
46 
47     bit_ctx->value = (bit_ctx->buffer[0] << 24) + (bit_ctx->buffer[1] << 16)
48                      + (bit_ctx->buffer[2] << 8) + (bit_ctx->buffer[3]);
49 
50     bit_ctx->pos += 4;
51 
52     bit_ctx->streamEndPos = len;
53     bit_ctx->strmError = bit_ctx->pos > bit_ctx->streamEndPos;
54 
55     FUN_T("FUN_OUT");
56 }
57 
vp8hwdDecodeBool(vpBoolCoder_t * bit_ctx,RK_S32 probability)58 static RK_U32 vp8hwdDecodeBool(vpBoolCoder_t *bit_ctx, RK_S32 probability)
59 {
60     RK_U32  bit = 0;
61     RK_U32  split;
62     RK_U32  bigsplit;
63     RK_U32  count = bit_ctx->count;
64     RK_U32  range = bit_ctx->range;
65     RK_U32  value = bit_ctx->value;
66 
67     FUN_T("FUN_IN");
68     split = 1 + (((range - 1) * probability) >> 8);
69     bigsplit = (split << 24);
70     range = split;
71 
72     if (value >= bigsplit) {
73         range = bit_ctx->range - split;
74         value = value - bigsplit;
75         bit = 1;
76     }
77 
78     if (range >= 0x80) {
79         bit_ctx->value = value;
80         bit_ctx->range = range;
81         return bit;
82     } else {
83         do {
84             range += range;
85             value += value;
86 
87             if (!--count) {
88                 /* no more stream to read? */
89                 if (bit_ctx->pos >= bit_ctx->streamEndPos) {
90                     bit_ctx->strmError = 1;
91                     mpp_log("vp8hwdDecodeBool read end");
92                     break;
93                 }
94                 count = 8;
95                 value |=  bit_ctx->buffer[bit_ctx->pos];
96                 bit_ctx->pos++;
97             }
98         } while (range < 0x80);
99     }
100 
101 
102     bit_ctx->count = count;
103     bit_ctx->value = value;
104     bit_ctx->range = range;
105 
106     FUN_T("FUN_OUT");
107     return bit;
108 }
109 
vp8hwdDecodeBool128(vpBoolCoder_t * bit_ctx)110 static RK_U32 vp8hwdDecodeBool128(vpBoolCoder_t *bit_ctx)
111 {
112     RK_U32 bit = 0;
113     RK_U32 split;
114     RK_U32 bigsplit;
115     RK_U32 count =  bit_ctx->count;
116     RK_U32 range = bit_ctx->range;
117     RK_U32 value = bit_ctx->value;
118 
119     FUN_T("FUN_IN");
120     split = (range + 1) >> 1;
121     bigsplit = (split << 24);
122     range = split;
123 
124     if (value >= bigsplit) {
125         range = (bit_ctx->range - split);
126         value = (value - bigsplit);
127         bit = 1;
128     }
129 
130     if (range >= 0x80) {
131         bit_ctx->value = value;
132         bit_ctx->range = range;
133 
134         FUN_T("FUN_OUT");
135         return bit;
136     } else {
137         range <<= 1;
138         value <<= 1;
139 
140         if (!--count) {
141             /* no more stream to read? */
142             if (bit_ctx->pos >= bit_ctx->streamEndPos) {
143                 bit_ctx->strmError = 1;
144                 mpp_log("vp8hwdDecodeBool128 read end");
145                 return 0; /* any value, not valid */
146             }
147             count = 8;
148             value |= bit_ctx->buffer[bit_ctx->pos];
149             bit_ctx->pos++;
150         }
151     }
152 
153     bit_ctx->count = count;
154     bit_ctx->value = value;
155     bit_ctx->range = range;
156 
157     FUN_T("FUN_OUT");
158     return bit;
159 }
160 
vp8hwdReadBits(vpBoolCoder_t * bit_ctx,RK_S32 bits)161 static RK_U32 vp8hwdReadBits(vpBoolCoder_t *bit_ctx, RK_S32 bits)
162 {
163     RK_U32 z = 0;
164     RK_S32 bit;
165 
166     FUN_T("FUN_IN");
167     for (bit = bits - 1; bit >= 0; bit--) {
168         z |= (vp8hwdDecodeBool128(bit_ctx) << bit);
169     }
170 
171     FUN_T("FUN_OUT");
172     return z;
173 }
174 
ScaleDimension(RK_U32 orig,RK_U32 scale)175 static RK_U32 ScaleDimension( RK_U32 orig, RK_U32 scale )
176 {
177 
178     FUN_T("FUN_IN");
179     switch (scale) {
180     case 0:
181         return orig;
182         break;
183     case 1: /* 5/4 */
184         return (5 * orig) / 4;
185         break;
186     case 2: /* 5/3 */
187         return (5 * orig) / 3;
188         break;
189     case 3: /* 2 */
190         return 2 * orig;
191         break;
192     }
193 
194     FUN_T("FUN_OUT");
195     return orig;
196 }
197 
DecodeQuantizerDelta(vpBoolCoder_t * bit_ctx)198 static RK_S32 DecodeQuantizerDelta(vpBoolCoder_t *bit_ctx)
199 {
200     RK_S32  result = 0;
201 
202     FUN_T("FUN_IN");
203     if (vp8hwdDecodeBool128(bit_ctx)) {
204         result = vp8hwdReadBits(bit_ctx, 4);
205         if (vp8hwdDecodeBool128(bit_ctx))
206             result = -result;
207     }
208 
209     FUN_T("FUN_OUT");
210     return result;
211 }
212 
vp8d_parser_init(void * ctx,ParserCfg * parser_cfg)213 MPP_RET vp8d_parser_init(void *ctx, ParserCfg *parser_cfg)
214 {
215     MPP_RET ret = MPP_OK;
216     VP8DContext *c = (VP8DContext *)ctx;
217     VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx;
218 
219     mpp_env_get_u32("vp8d_debug", &vp8d_debug, 0);
220     FUN_T("FUN_IN");
221     if (p == NULL) {
222         p = (VP8DParserContext_t*)mpp_calloc(VP8DParserContext_t, 1);
223         if (NULL == p) {
224             mpp_err("vp8d malloc VP8DParserContext_t fail");
225             FUN_T("FUN_OUT");
226             return MPP_ERR_NOMEM;
227         }
228         c->parse_ctx = p;
229     }
230     p->packet_slots = parser_cfg->packet_slots;
231     p->frame_slots = parser_cfg->frame_slots;
232 
233     mpp_buf_slot_setup(p->frame_slots, 15);
234 
235     p->dxva_ctx = mpp_calloc(DXVA_PicParams_VP8, 1);
236 
237     if (NULL == p->dxva_ctx) {
238         mpp_err("vp8d malloc dxva_ctx fail");
239         FUN_T("FUN_OUT");
240         return MPP_ERR_NOMEM;
241     }
242     p->decMode = VP8HWD_VP8;
243     p->bitstream_sw_buf = mpp_malloc(RK_U8, VP8D_BUF_SIZE_BITMEM);
244     mpp_packet_init(&p->input_packet, p->bitstream_sw_buf,
245                     VP8D_BUF_SIZE_BITMEM);
246     p->max_stream_size = VP8D_BUF_SIZE_BITMEM;
247 
248     FUN_T("FUN_OUT");
249     return ret;
250 }
251 
vp8d_unref_frame(VP8DParserContext_t * p,VP8Frame * frame)252 static void vp8d_unref_frame(VP8DParserContext_t *p, VP8Frame *frame)
253 {
254 
255     FUN_T("FUN_IN");
256     if (NULL == frame || frame->ref_count <= 0
257         || frame->slot_index >= 0x7f) {
258         mpp_err("ref count alreay is zero");
259         FUN_T("FUN_OUT");
260         return;
261     }
262 
263     frame->ref_count--;
264     if (!frame->ref_count) {
265         if (frame->slot_index < 0x7f) {
266             MppBuffer framebuf = NULL;
267             if (frame->invisible) {
268                 mpp_buf_slot_get_prop(p->frame_slots, frame->slot_index, SLOT_BUFFER, &framebuf);
269                 mpp_buffer_put(framebuf);
270                 frame->invisible = 0;
271             }
272             mpp_buf_slot_clr_flag(p->frame_slots, frame->slot_index, SLOT_CODEC_USE);
273         }
274         frame->slot_index = 0xff;
275         mpp_frame_deinit(&frame->f);
276         mpp_free(frame);
277         frame = NULL;
278     }
279 
280     FUN_T("FUN_OUT");
281     return;
282 }
283 
vp8d_unref_allframe(VP8DParserContext_t * p)284 static void vp8d_unref_allframe(VP8DParserContext_t *p)
285 {
286 
287     FUN_T("FUN_IN");
288     if (NULL != p->frame_out) {
289         vp8d_unref_frame(p, p->frame_out);
290         p->frame_out = NULL;
291     }
292 
293     if (NULL != p->frame_ref) {
294         vp8d_unref_frame(p, p->frame_ref);
295         p->frame_ref = NULL;
296     }
297 
298     if (NULL != p->frame_golden) {
299         vp8d_unref_frame(p, p->frame_golden);
300         p->frame_golden = NULL;
301     }
302 
303     if (NULL != p->frame_alternate) {
304         vp8d_unref_frame(p, p->frame_alternate);
305         p->frame_alternate = NULL;
306     }
307 
308     FUN_T("FUN_OUT");
309     return;
310 }
311 
vp8d_parser_deinit(void * ctx)312 MPP_RET vp8d_parser_deinit(void *ctx)
313 {
314     MPP_RET ret = MPP_OK;
315     VP8DContext *c = (VP8DContext *)ctx;
316     VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx;
317 
318     FUN_T("FUN_IN");
319 
320     if (NULL != p->bitstream_sw_buf) {
321         mpp_free(p->bitstream_sw_buf);
322         p->bitstream_sw_buf = NULL;
323     }
324 
325     if (NULL != p->dxva_ctx) {
326         mpp_free(p->dxva_ctx);
327         p->dxva_ctx = NULL;
328     }
329 
330     vp8d_unref_allframe(p);
331 
332     if (p->input_packet) {
333         mpp_packet_deinit(&p->input_packet);
334         p->input_packet = NULL;
335     }
336 
337     if (p->stream_fp)
338         fclose(p->stream_fp);
339 
340     if ( NULL != p) {
341         mpp_free(p);
342     }
343     FUN_T("FUN_OUT");
344     return ret;
345 }
346 /*!
347 ***********************************************************************
348 * \brief
349 *   reset
350 ***********************************************************************
351 */
vp8d_parser_reset(void * ctx)352 MPP_RET vp8d_parser_reset(void *ctx)
353 {
354     MPP_RET ret = MPP_OK;
355     VP8DContext *c = (VP8DContext *)ctx;
356     VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx;
357 
358     FUN_T("FUN_IN");
359     vp8d_unref_allframe(p);
360     p->needKeyFrame = 0;
361     p->eos = 0;
362     FUN_T("FUN_OUT");
363     return ret;
364 }
365 
366 /*!
367 ***********************************************************************
368 * \brief
369 *   flush
370 ***********************************************************************
371 */
vp8d_parser_flush(void * ctx)372 MPP_RET vp8d_parser_flush(void *ctx)
373 {
374     MPP_RET ret = MPP_OK;
375 
376     FUN_T("FUN_IN");
377     (void) ctx;
378     FUN_T("FUN_OUT");
379     return ret;
380 }
381 
382 /*!
383 ***********************************************************************
384 * \brief
385 *   control/perform
386 ***********************************************************************
387 */
vp8d_parser_control(void * ctx,MpiCmd cmd_type,void * param)388 MPP_RET vp8d_parser_control(void *ctx, MpiCmd cmd_type, void *param)
389 {
390     MPP_RET ret = MPP_OK;
391 
392     FUN_T("FUN_IN");
393     (void)ctx;
394     (void)cmd_type;
395     (void)param;
396 
397     FUN_T("FUN_OUT");
398     return ret;
399 }
400 
401 
402 /*!
403 ***********************************************************************
404 * \brief
405 *   prepare
406 ***********************************************************************
407 */
408 
vp8d_parser_split_frame(RK_U8 * src,RK_U32 src_size,RK_U8 * dst,RK_U32 * dst_size)409 static MPP_RET vp8d_parser_split_frame(RK_U8 *src, RK_U32 src_size,
410                                        RK_U8 *dst, RK_U32 *dst_size)
411 {
412     MPP_RET ret = MPP_OK;
413 
414     FUN_T("FUN_IN");
415     memcpy(dst, src, src_size);;
416     *dst_size = src_size;
417 
418     (void)dst;
419 
420     FUN_T("FUN_OUT");
421     return ret;
422 }
423 
424 
vp8d_parser_prepare(void * ctx,MppPacket pkt,HalDecTask * task)425 MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task)
426 {
427     MPP_RET ret = MPP_OK;
428     RK_U32 out_size = 0, len_in = 0;
429     RK_U8 * pos = NULL;
430     RK_U8 *buf = NULL;
431     VP8DContext *c = (VP8DContext *)ctx;
432 
433     VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx;
434     MppPacket input_packet = p->input_packet;
435 
436     FUN_T("FUN_IN");
437     task->valid = 0;
438 
439 
440     buf = pos = mpp_packet_get_pos(pkt);
441     p->pts = mpp_packet_get_pts(pkt);
442     p->dts = mpp_packet_get_dts(pkt);
443 
444     len_in = (RK_U32)mpp_packet_get_length(pkt),
445     p->eos = mpp_packet_get_eos(pkt);
446     // mpp_log("len_in = %d",len_in);
447     if (len_in > p->max_stream_size) {
448         mpp_free(p->bitstream_sw_buf);
449         p->bitstream_sw_buf = NULL;
450         p->bitstream_sw_buf = mpp_malloc(RK_U8, (len_in + 1024));
451         if (NULL == p->bitstream_sw_buf) {
452             mpp_err("vp8d_parser realloc fail");
453             return MPP_ERR_NOMEM;
454         }
455         p->max_stream_size = len_in + 1024;
456     }
457 
458     vp8d_parser_split_frame(buf,
459                             len_in,
460                             p->bitstream_sw_buf,
461                             &out_size);
462     pos += out_size;
463 
464     mpp_packet_set_pos(pkt, pos);
465 
466     if (out_size == 0 && p->eos) {
467         task->flags.eos = p->eos;
468         return ret;
469     }
470 
471 
472 
473     // mpp_log("p->bitstream_sw_buf = 0x%x", p->bitstream_sw_buf);
474     // mpp_log("out_size = 0x%x", out_size);
475     mpp_packet_set_data(input_packet, p->bitstream_sw_buf);
476     mpp_packet_set_size(input_packet, p->max_stream_size);
477     mpp_packet_set_length(input_packet, out_size);
478     p->stream_size = out_size;
479     task->input_packet = input_packet;
480     task->valid = 1;
481 
482     FUN_T("FUN_OUT");
483     return ret;
484 }
485 
486 static MPP_RET
vp8d_convert_to_syntx(VP8DParserContext_t * p,HalDecTask * in_task)487 vp8d_convert_to_syntx( VP8DParserContext_t *p, HalDecTask *in_task)
488 {
489     MPP_RET ret = MPP_OK;
490     RK_U32 i, tmp;
491     RK_U32 byteOffset = 0, extraBytesPacked = 0;
492     DXVA_PicParams_VP8 *pic_param = p->dxva_ctx;
493 
494     FUN_T("FUN_IN");
495     tmp = (p->bitstr.pos) * 8 + (8 - p->bitstr.count);
496 
497     if (p->frameTagSize == 4)
498         tmp += 8;
499 
500     if (p->decMode == VP8HWD_VP8 && p->keyFrame)
501         extraBytesPacked += 7;
502 
503     tmp += extraBytesPacked * 8;
504     byteOffset = tmp / 8;
505     pic_param->stream_start_bit = (byteOffset & 0x07U) * 8;
506     byteOffset &= (~0x07U);  /* align the base */
507     pic_param->stream_start_offset = byteOffset;
508 
509     pic_param->stream_start_bit += (tmp & 0x7);
510 
511     pic_param->frame_type = !p->keyFrame;
512     pic_param->stVP8Segments.segmentation_enabled = p->segmentationEnabled;
513     pic_param->stVP8Segments.update_mb_segmentation_map =
514         p->segmentationMapUpdate;
515     pic_param->mode_ref_lf_delta_enabled = p->modeRefLfEnabled;
516     pic_param->mb_no_coeff_skip = p->coeffSkipMode;
517     pic_param->width               = p->width;
518     pic_param->height              = p->height;
519     pic_param->decMode             = p->decMode;
520     pic_param->filter_type      = p->loopFilterType;
521     pic_param->sharpness    = p->loopFilterSharpness;
522     pic_param->filter_level     = p->loopFilterLevel;
523     pic_param->stVP8Segments.update_mb_segmentation_data =
524         p->segmentFeatureMode;
525     pic_param->version      = p->vpVersion;
526     pic_param->bool_value          = ((p->bitstr.value >> 24) & (0xFFU));
527     pic_param->bool_range          = (p->bitstr.range & (0xFFU));
528     pic_param->frameTagSize        = p->frameTagSize;
529     pic_param->streamEndPos        = p->bitstr.streamEndPos;
530     pic_param->log2_nbr_of_dct_partitions = p->nbrDctPartitions;
531     pic_param->offsetToDctParts    = p->offsetToDctParts;
532 
533     pic_param->y1ac_delta_q = p->qpYAc;
534     pic_param->y1dc_delta_q = p->qpYDc;
535     pic_param->y2ac_delta_q = p->qpY2Ac;
536     pic_param->y2dc_delta_q = p->qpY2Dc;
537     pic_param->uvac_delta_q = p->qpChAc;
538     pic_param->uvdc_delta_q = p->qpChDc;
539     pic_param->probe_skip_false = p->probMbSkipFalse;
540     pic_param->prob_intra = p->probIntra;
541     pic_param->prob_last = p->probRefLast;
542     pic_param->prob_golden = p->probRefGolden;
543 
544     memcpy(pic_param->vp8_coef_update_probs, p->entropy.probCoeffs,
545            sizeof(pic_param->vp8_coef_update_probs));
546     memcpy(pic_param->vp8_mv_update_probs, p->entropy.probMvContext,
547            sizeof(pic_param->vp8_mv_update_probs));
548 
549     for ( i = 0; i < 3; i++) {
550         pic_param->intra_chroma_prob[i] = p->entropy.probChromaPredMode[i];
551         pic_param->stVP8Segments.mb_segment_tree_probs[i] = p->probSegment[i];
552     }
553 
554     pic_param->ref_frame_sign_bias_golden = p->refFrameSignBias[0];
555     pic_param->ref_frame_sign_bias_altref = p->refFrameSignBias[1];
556 
557 
558     for (i = 0; i < 4; i++) {
559         pic_param->stVP8Segments.segment_feature_data[0][i] = p->segmentQp[i];
560         pic_param->ref_lf_deltas[i] = p->mbRefLfDelta[i];
561         pic_param->mode_lf_deltas[i] = p->mbModeLfDelta[i];
562         pic_param->stVP8Segments.segment_feature_data[1][i] =
563             p->segmentLoopfilter[i];
564         pic_param->intra_16x16_prob[i] = p->entropy.probLuma16x16PredMode[i];
565     }
566 
567     p->dxva_ctx->CurrPic.Index7Bits = p->frame_out->slot_index;
568     memset(in_task->refer, -1, sizeof(in_task->refer));
569 
570     if (p->frame_ref != NULL) {
571         pic_param->lst_fb_idx.Index7Bits = p->frame_ref->slot_index;
572         mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref->slot_index,
573                               SLOT_HAL_INPUT);
574         in_task->refer[0] = p->frame_ref->slot_index;
575     } else {
576         pic_param->lst_fb_idx.Index7Bits = 0x7f;
577     }
578 
579     if (p->frame_golden != NULL) {
580         pic_param->gld_fb_idx.Index7Bits = p->frame_golden->slot_index;
581         mpp_buf_slot_set_flag(p->frame_slots, p->frame_golden->slot_index,
582                               SLOT_HAL_INPUT);
583         in_task->refer[1] = p->frame_golden->slot_index;
584     } else {
585         pic_param->gld_fb_idx.Index7Bits = 0x7f;
586     }
587 
588     if (p->frame_alternate != NULL) {
589         pic_param->alt_fb_idx.Index7Bits = p->frame_alternate->slot_index;
590         mpp_buf_slot_set_flag(p->frame_slots, p->frame_alternate->slot_index,
591                               SLOT_HAL_INPUT);
592         in_task->refer[2] = p->frame_alternate->slot_index;
593     } else {
594         pic_param->alt_fb_idx.Index7Bits = 0x7f;
595     }
596 
597     memcpy(pic_param->dctPartitionOffsets, p->dctPartitionOffsets,
598            sizeof(p->dctPartitionOffsets));
599 
600     FUN_T("FUN_OUT");
601     return ret;
602 }
603 
vp8d_alloc_frame(VP8DParserContext_t * p)604 static MPP_RET vp8d_alloc_frame(VP8DParserContext_t *p)
605 {
606     MPP_RET ret = MPP_OK;
607 
608     FUN_T("FUN_IN");
609     if (NULL == p->frame_out) {
610         p->frame_out = mpp_calloc(VP8Frame, 1);
611         if (NULL == p->frame_out) {
612             mpp_err("alloc vp8 frame fail");
613             return MPP_ERR_NOMEM;
614         }
615 
616         if (NULL == p->frame_out->f) {
617             mpp_frame_init(&p->frame_out->f);
618             if (NULL == p->frame_out->f) {
619                 mpp_err("alloc vp8 mpp frame fail");
620                 return MPP_ERR_NOMEM;
621             }
622         }
623         p->frame_out->slot_index = 0xff;
624         p->frame_out->invisible = !p->showFrame;
625     }
626 
627     if (p->frame_out->slot_index == 0xff) {
628         mpp_frame_set_width(p->frame_out->f, p->width);
629         mpp_frame_set_height(p->frame_out->f, p->height);
630         mpp_frame_set_hor_stride(p->frame_out->f, 0);
631         mpp_frame_set_ver_stride(p->frame_out->f, 0);
632         mpp_frame_set_errinfo(p->frame_out->f, 0);
633         mpp_frame_set_pts(p->frame_out->f, p->pts);
634         mpp_frame_set_dts(p->frame_out->f, p->dts);
635         ret = mpp_buf_slot_get_unused(p->frame_slots,
636                                       &p->frame_out->slot_index);
637         if (MPP_OK != ret) {
638             mpp_err("vp8 buf_slot_get_unused get fail");
639             return ret;
640         }
641         mpp_buf_slot_set_prop(p->frame_slots, p->frame_out->slot_index,
642                               SLOT_FRAME, p->frame_out->f);
643         mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index,
644                               SLOT_CODEC_USE);
645         mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index,
646                               SLOT_HAL_OUTPUT);
647         mpp_frame_set_mode(p->frame_out->f, 0);
648 
649         if (p->showFrame) {
650             mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index,
651                                   SLOT_QUEUE_USE);
652             mpp_buf_slot_enqueue(p->frame_slots, p->frame_out->slot_index,
653                                  QUEUE_DISPLAY);
654         }
655         p->frame_out->ref_count++;
656     }
657 
658     FUN_T("FUN_OUT");
659     return ret;
660 }
661 
vp8d_ref_frame(VP8Frame * frame)662 static void vp8d_ref_frame(VP8Frame *frame)
663 {
664 
665     FUN_T("FUN_IN");
666     if ((NULL == frame) || (frame->slot_index >= 0x7f)) {
667         mpp_err("frame is null or slot_index is no valid");
668         return;
669     }
670     frame->ref_count++;
671 
672     FUN_T("FUN_OUT");
673 }
674 
675 
vp8d_ref_update(VP8DParserContext_t * p)676 static MPP_RET vp8d_ref_update(VP8DParserContext_t *p)
677 {
678 
679     FUN_T("FUN_IN");
680     if (p->decMode != VP8HWD_WEBP) {
681         if (p->copyBufferToAlternate == 1) {
682             if (NULL != p->frame_alternate) {
683                 vp8d_unref_frame(p, p->frame_alternate);
684                 p->frame_alternate = NULL;
685             }
686             p->frame_alternate = p->frame_ref;
687             vp8d_ref_frame(p->frame_alternate);
688         } else if (p->copyBufferToAlternate == 2) {
689             if (NULL != p->frame_alternate) {
690                 vp8d_unref_frame(p, p->frame_alternate);
691                 p->frame_alternate = NULL;
692             }
693             p->frame_alternate = p->frame_golden;
694             vp8d_ref_frame(p->frame_alternate);
695         }
696 
697         if (p->copyBufferToGolden == 1) {
698             if (NULL != p->frame_golden) {
699                 vp8d_unref_frame(p, p->frame_golden);
700                 p->frame_golden = NULL;
701             }
702             p->frame_golden = p->frame_ref;
703             vp8d_ref_frame(p->frame_golden);
704         } else if (p->copyBufferToGolden == 2) {
705             if (NULL != p->frame_golden) {
706                 vp8d_unref_frame(p, p->frame_golden);
707                 p->frame_golden = NULL;
708             }
709             p->frame_golden = p->frame_alternate;
710             vp8d_ref_frame(p->frame_golden);
711         }
712 
713         if (p->refreshGolden) {
714             if (NULL != p->frame_golden) {
715                 vp8d_unref_frame(p, p->frame_golden);
716                 p->frame_golden = NULL;
717             }
718             p->frame_golden = p->frame_out;
719             vp8d_ref_frame(p->frame_golden);
720         }
721 
722         if (p->refreshAlternate) {
723             if (NULL != p->frame_alternate) {
724                 vp8d_unref_frame(p, p->frame_alternate);
725                 p->frame_alternate = NULL;
726             }
727             p->frame_alternate = p->frame_out;
728             vp8d_ref_frame(p->frame_out);
729         }
730 
731         if (p->refreshLast) {
732             if (NULL != p->frame_ref) {
733                 vp8d_unref_frame(p, p->frame_ref);
734                 p->frame_ref = NULL;
735             }
736             p->frame_ref = p->frame_out;
737             vp8d_ref_frame(p->frame_ref);
738         }
739         vp8d_unref_frame(p, p->frame_out);
740         p->frame_out = NULL;
741     }
742 
743     FUN_T("FUN_OUT");
744     return 0;
745 }
746 
vp8hwdResetProbs(VP8DParserContext_t * p)747 static void vp8hwdResetProbs(VP8DParserContext_t *p)
748 {
749     RK_U32 i, j, k, l;
750     static const RK_U32 Vp7DefaultScan[] = {
751         0,  1,  4,  8,  5,  2,  3,  6,
752         9, 12, 13, 10,  7, 11, 14, 15,
753     };
754 
755     FUN_T("FUN_IN");
756     for ( i = 0 ; i < 16 ; ++i )
757         p->vp7ScanOrder[i] = Vp7DefaultScan[i];
758 
759 
760     /* Intra-prediction modes */
761     p->entropy.probLuma16x16PredMode[0] = 112;
762     p->entropy.probLuma16x16PredMode[1] = 86;
763     p->entropy.probLuma16x16PredMode[2] = 140;
764     p->entropy.probLuma16x16PredMode[3] = 37;
765     p->entropy.probChromaPredMode[0] = 162;
766     p->entropy.probChromaPredMode[1] = 101;
767     p->entropy.probChromaPredMode[2] = 204;
768 
769     for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++)
770         p->mbRefLfDelta[i] = 0;
771 
772     for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++)
773         p->mbModeLfDelta[i] = 0;
774 
775     /* MV context */
776     k = 0;
777     if (p->decMode == VP8HWD_VP8) {
778         for ( i = 0 ; i < 2 ; ++i )
779             for ( j = 0 ; j < VP8_MV_PROBS_PER_COMPONENT ; ++j, ++k )
780                 p->entropy.probMvContext[i][j] = Vp8DefaultMvProbs[i][j];
781     } else {
782         for ( i = 0 ; i < 2 ; ++i )
783             for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j, ++k )
784                 p->entropy.probMvContext[i][j] = Vp7DefaultMvProbs[i][j];
785     }
786 
787     /* Coefficients */
788     for ( i = 0 ; i < 4 ; ++i )
789         for ( j = 0 ; j < 8 ; ++j )
790             for ( k = 0 ; k < 3 ; ++k )
791                 for ( l = 0 ; l < 11 ; ++l )
792                     p->entropy.probCoeffs[i][j][k][l] =
793                         DefaultCoeffProbs[i][j][k][l];
794 
795     FUN_T("FUN_OUT");
796 }
797 
vp8hwdDecodeCoeffUpdate(VP8DParserContext_t * p)798 static void vp8hwdDecodeCoeffUpdate(VP8DParserContext_t *p)
799 {
800     RK_U32 i, j, k, l;
801 
802     FUN_T("FUN_IN");
803     for ( i = 0; i < 4; i++ ) {
804         for ( j = 0; j < 8; j++ ) {
805             for ( k = 0; k < 3; k++ ) {
806                 for ( l = 0; l < 11; l++ ) {
807                     if (vp8hwdDecodeBool(&p->bitstr,
808                                          CoeffUpdateProbs[i][j][k][l]))
809                         p->entropy.probCoeffs[i][j][k][l] =
810                             vp8hwdReadBits(&p->bitstr, 8);
811                 }
812             }
813         }
814     }
815     FUN_T("FUN_OUT");
816 }
817 
vp8_header_parser(VP8DParserContext_t * p,RK_U8 * pbase,RK_U32 size)818 static MPP_RET vp8_header_parser(VP8DParserContext_t *p, RK_U8 *pbase,
819                                  RK_U32 size)
820 {
821     RK_U32  tmp;
822     int     i, j;
823     vpBoolCoder_t *bit_ctx = &p->bitstr;
824 
825     FUN_T("FUN_IN");
826     if (p->keyFrame) {
827         tmp = (pbase[0] << 16) | (pbase[1] << 8) | (pbase[2] << 0);
828         if (tmp != VP8_KEY_FRAME_START_CODE)
829             return MPP_ERR_PROTOL;
830         tmp = (pbase[3] << 0) | (pbase[4] << 8);
831         p->width = tmp & 0x3fff;
832         p->scaledWidth = ScaleDimension(p->width, tmp >> 14);
833         tmp = (pbase[5] << 0) | (pbase[6] << 8);
834         p->height = tmp & 0x3fff;
835         p->scaledHeight = ScaleDimension(p->height, tmp >> 14);
836         pbase += 7;
837         size -= 7;
838     }
839     vp8hwdBoolStart(bit_ctx, pbase, size);
840     if (p->keyFrame) {
841         p->colorSpace = (vpColorSpace_e)vp8hwdDecodeBool128(bit_ctx);
842         p->clamping = vp8hwdDecodeBool128(bit_ctx);
843     }
844     p->segmentationEnabled = vp8hwdDecodeBool128(bit_ctx);
845     p->segmentationMapUpdate = 0;
846     if (p->segmentationEnabled) {
847         p->segmentationMapUpdate = vp8hwdDecodeBool128(bit_ctx);
848         if (vp8hwdDecodeBool128(bit_ctx)) {    /* Segmentation map update */
849             p->segmentFeatureMode = vp8hwdDecodeBool128(bit_ctx);
850             memset(&p->segmentQp[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32));
851             memset(&p->segmentLoopfilter[0], 0,
852                    MAX_NBR_OF_SEGMENTS * sizeof(RK_S32));
853             for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) {
854                 if (vp8hwdDecodeBool128(bit_ctx)) {
855                     p->segmentQp[i] = vp8hwdReadBits(bit_ctx, 7);
856                     if (vp8hwdDecodeBool128(bit_ctx))
857                         p->segmentQp[i] = -p->segmentQp[i];
858                 }
859             }
860             for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) {
861                 if (vp8hwdDecodeBool128(bit_ctx)) {
862                     p->segmentLoopfilter[i] = vp8hwdReadBits(bit_ctx, 6);
863                     if (vp8hwdDecodeBool128(bit_ctx))
864                         p->segmentLoopfilter[i] = -p->segmentLoopfilter[i];
865                 }
866             }
867         }
868         if (p->segmentationMapUpdate) {
869             p->probSegment[0] = 255;
870             p->probSegment[1] = 255;
871             p->probSegment[2] = 255;
872             for (i = 0; i < 3; i++) {
873                 if (vp8hwdDecodeBool128(bit_ctx)) {
874                     p->probSegment[i] = vp8hwdReadBits(bit_ctx, 8);
875                 }
876             }
877         }
878         if (bit_ctx->strmError) {
879             mpp_err_f("paser header stream no enough");
880             FUN_T("FUN_OUT");
881             return MPP_ERR_STREAM;
882         }
883     }
884     p->loopFilterType = vp8hwdDecodeBool128(bit_ctx);
885     p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6);
886     p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3);
887     p->modeRefLfEnabled = vp8hwdDecodeBool128(bit_ctx);
888     if (p->modeRefLfEnabled) {
889         if (vp8hwdDecodeBool128(bit_ctx)) {
890             for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) {
891                 if (vp8hwdDecodeBool128(bit_ctx)) {
892                     p->mbRefLfDelta[i] = vp8hwdReadBits(bit_ctx, 6);
893                     if (vp8hwdDecodeBool128(bit_ctx))
894                         p->mbRefLfDelta[i] = -p->mbRefLfDelta[i];
895                 }
896             }
897             for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) {
898                 if (vp8hwdDecodeBool128(&p->bitstr)) {
899                     p->mbModeLfDelta[i] = vp8hwdReadBits(bit_ctx, 6);
900                     if (vp8hwdDecodeBool128(bit_ctx))
901                         p->mbModeLfDelta[i] = -p->mbModeLfDelta[i];
902                 }
903             }
904         }
905     }
906     if (bit_ctx->strmError) {
907         mpp_err_f("paser header stream no enough");
908         FUN_T("FUN_OUT");
909         return MPP_ERR_STREAM;
910     }
911     p->nbrDctPartitions = vp8hwdReadBits(bit_ctx, 2);
912     p->qpYAc = vp8hwdReadBits(bit_ctx, 7);
913     p->qpYDc = DecodeQuantizerDelta(bit_ctx);
914     p->qpY2Dc = DecodeQuantizerDelta(bit_ctx);
915     p->qpY2Ac = DecodeQuantizerDelta(bit_ctx);
916     p->qpChDc = DecodeQuantizerDelta(bit_ctx);
917     p->qpChAc = DecodeQuantizerDelta(bit_ctx);
918     if (p->keyFrame) {
919         p->refreshGolden          = 1;
920         p->refreshAlternate       = 1;
921         p->copyBufferToGolden     = 0;
922         p->copyBufferToAlternate  = 0;
923 
924         /* Refresh entropy probs */
925         p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx);
926 
927         p->refFrameSignBias[0] = 0;
928         p->refFrameSignBias[1] = 0;
929         p->refreshLast = 1;
930     } else {
931         /* Refresh golden */
932         p->refreshGolden = vp8hwdDecodeBool128(bit_ctx);
933         /* Refresh alternate */
934         p->refreshAlternate = vp8hwdDecodeBool128(bit_ctx);
935         if ( p->refreshGolden == 0 ) {
936             /* Copy to golden */
937             p->copyBufferToGolden = vp8hwdReadBits(bit_ctx, 2);
938         } else
939             p->copyBufferToGolden = 0;
940 
941         if ( p->refreshAlternate == 0 ) {
942             /* Copy to alternate */
943             p->copyBufferToAlternate = vp8hwdReadBits(bit_ctx, 2);
944         } else
945             p->copyBufferToAlternate = 0;
946 
947         /* Sign bias for golden frame */
948         p->refFrameSignBias[0] = vp8hwdDecodeBool128(bit_ctx);
949         /* Sign bias for alternate frame */
950         p->refFrameSignBias[1] = vp8hwdDecodeBool128(bit_ctx);
951         /* Refresh entropy probs */
952         p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx);
953         /* Refresh last */
954         p->refreshLast = vp8hwdDecodeBool128(bit_ctx);
955     }
956 
957     /* Make a "backup" of current entropy probabilities if refresh is not set */
958     if (p->refreshEntropyProbs == 0) {
959         memcpy((void*)&p->entropyLast, (void*)&p->entropy,
960                (unsigned long)sizeof(vp8EntropyProbs_t));
961         memcpy( (void*)p->vp7PrevScanOrder, (void*)p->vp7ScanOrder,
962                 (unsigned long)sizeof(p->vp7ScanOrder));
963     }
964 
965     vp8hwdDecodeCoeffUpdate(p);
966     p->coeffSkipMode =  vp8hwdDecodeBool128(bit_ctx);
967     if (!p->keyFrame) {
968         RK_U32  mvProbs;
969         if (p->coeffSkipMode)
970             p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8);
971         p->probIntra = vp8hwdReadBits(bit_ctx, 8);
972         p->probRefLast = vp8hwdReadBits(bit_ctx, 8);
973         p->probRefGolden = vp8hwdReadBits(bit_ctx, 8);
974         if (vp8hwdDecodeBool128(bit_ctx)) {
975             for (i = 0; i < 4; i++)
976                 p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8);
977         }
978         if (vp8hwdDecodeBool128(bit_ctx)) {
979             for (i = 0; i < 3; i++)
980                 p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8);
981         }
982         mvProbs = VP8_MV_PROBS_PER_COMPONENT;
983         for ( i = 0 ; i < 2 ; ++i ) {
984             for ( j = 0 ; j < (RK_S32)mvProbs ; ++j ) {
985                 if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j]) == 1) {
986                     tmp = vp8hwdReadBits(bit_ctx, 7);
987                     if ( tmp )
988                         tmp = tmp << 1;
989                     else
990                         tmp = 1;
991                     p->entropy.probMvContext[i][j] = tmp;
992                 }
993             }
994         }
995     } else {
996         if (p->coeffSkipMode)
997             p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8);
998     }
999     if (bit_ctx->strmError) {
1000         mpp_err_f("paser header stream no enough");
1001         FUN_T("FUN_OUT");
1002         return MPP_ERR_STREAM;
1003     }
1004     FUN_T("FUN_OUT");
1005     return MPP_OK;
1006 }
1007 
1008 static MPP_RET
vp7_header_parser(VP8DParserContext_t * p,RK_U8 * pbase,RK_U32 size)1009 vp7_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size)
1010 {
1011     RK_U32  tmp;
1012     int     i, j;
1013 
1014     FUN_T("FUN_IN");
1015     vpBoolCoder_t *bit_ctx = &p->bitstr;
1016     vp8hwdBoolStart(bit_ctx, pbase, size);
1017 
1018     if (p->keyFrame) {
1019         p->width = vp8hwdReadBits(bit_ctx, 12);
1020         p->height = vp8hwdReadBits(bit_ctx, 12);
1021         tmp = vp8hwdReadBits(bit_ctx, 2);
1022         p->scaledWidth = ScaleDimension(p->width, tmp);
1023         tmp = vp8hwdReadBits(bit_ctx, 2);
1024         p->scaledHeight = ScaleDimension(p->height, tmp);
1025     }
1026     {
1027         const RK_U32 vp70FeatureBits[4] = { 7, 6, 0, 8 };
1028         const RK_U32 vp71FeatureBits[4] = { 7, 6, 0, 5 };
1029         const RK_U32 *featureBits;
1030         if (p->vpVersion == 0)
1031             featureBits = vp70FeatureBits;
1032         else
1033             featureBits = vp71FeatureBits;
1034         for (i = 0; i < MAX_NBR_OF_VP7_MB_FEATURES; i++) {
1035             if (vp8hwdDecodeBool128(bit_ctx)) {
1036                 tmp = vp8hwdReadBits(bit_ctx, 8);
1037                 for (j = 0; j < 3; j++) {
1038                     if (vp8hwdDecodeBool128(bit_ctx))
1039                         tmp = vp8hwdReadBits(bit_ctx, 8);
1040                 }
1041                 if (featureBits[i]) {
1042                     for (j = 0; j < 4; j++) {
1043                         if (vp8hwdDecodeBool128(bit_ctx))
1044                             tmp = vp8hwdReadBits(bit_ctx, featureBits[i]);
1045                     }
1046                 }
1047                 FUN_T("FUN_OUT");
1048                 return MPP_ERR_PROTOL;
1049             }
1050 
1051         }
1052         p->nbrDctPartitions = 0;
1053     }
1054     p->qpYAc = (RK_S32)vp8hwdReadBits(bit_ctx, 7 );
1055     p->qpYDc  = vp8hwdReadBits(bit_ctx, 1 )
1056                 ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc;
1057     p->qpY2Dc = vp8hwdReadBits(bit_ctx, 1 )
1058                 ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc;
1059     p->qpY2Ac = vp8hwdReadBits(bit_ctx, 1 )
1060                 ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc;
1061     p->qpChDc = vp8hwdReadBits(bit_ctx, 1 )
1062                 ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc;
1063     p->qpChAc = vp8hwdReadBits(bit_ctx, 1 )
1064                 ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc;
1065     if (!p->keyFrame) {
1066         p->refreshGolden = vp8hwdDecodeBool128(bit_ctx);
1067         if (p->vpVersion >= 1) {
1068             p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx);
1069             p->refreshLast = vp8hwdDecodeBool128(bit_ctx);
1070         } else {
1071             p->refreshEntropyProbs = 1;
1072             p->refreshLast = 1;
1073         }
1074     } else {
1075         p->refreshGolden = 1;
1076         p->refreshAlternate = 1;
1077         p->copyBufferToGolden = 0;
1078         p->copyBufferToAlternate = 0;
1079         if (p->vpVersion >= 1)
1080             p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx);
1081         else
1082             p->refreshEntropyProbs = 1;
1083         p->refFrameSignBias[0] = 0;
1084         p->refFrameSignBias[1] = 0;
1085         p->refreshLast = 1;
1086     }
1087 
1088     if (!p->refreshEntropyProbs) {
1089         memcpy(&p->entropyLast, &p->entropy,
1090                (unsigned long)sizeof(vp8EntropyProbs_t));
1091         memcpy(p->vp7PrevScanOrder, p->vp7ScanOrder,
1092                (unsigned long)sizeof(p->vp7ScanOrder));
1093     }
1094     if (p->refreshLast) {
1095         if (vp8hwdDecodeBool128(bit_ctx)) {
1096             tmp = vp8hwdReadBits(bit_ctx, 8);
1097             tmp = vp8hwdReadBits(bit_ctx, 8);
1098             FUN_T("FUN_OUT");
1099             return MPP_ERR_STREAM;
1100         }
1101     }
1102     if (p->vpVersion == 0) {
1103         p->loopFilterType = vp8hwdDecodeBool128(bit_ctx);
1104     }
1105     if (vp8hwdDecodeBool128(bit_ctx)) {
1106         static const RK_U32 Vp7DefaultScan[] = {
1107             0,  1,  4,  8,  5,  2,  3,  6,
1108             9, 12, 13, 10,  7, 11, 14, 15,
1109         };
1110         p->vp7ScanOrder[0] = 0;
1111         for (i = 1; i < 16; i++)
1112             p->vp7ScanOrder[i] = Vp7DefaultScan[vp8hwdReadBits(bit_ctx, 4)];
1113     }
1114     if (p->vpVersion >= 1)
1115         p->loopFilterType = vp8hwdDecodeBool128(bit_ctx);
1116     p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6);
1117     p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3);
1118     vp8hwdDecodeCoeffUpdate(p);
1119     if (!p->keyFrame) {
1120         p->probIntra = vp8hwdReadBits(bit_ctx, 8);
1121         p->probRefLast = vp8hwdReadBits(bit_ctx, 8);
1122         if (vp8hwdDecodeBool128(bit_ctx)) {
1123             for (i = 0; i < 4; i++)
1124                 p->entropy.probLuma16x16PredMode[i] =
1125                     vp8hwdReadBits(bit_ctx, 8);
1126         }
1127         if (vp8hwdDecodeBool128(bit_ctx)) {
1128             for (i = 0; i < 3; i++)
1129                 p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8);
1130         }
1131         for ( i = 0 ; i < 2 ; ++i ) {
1132             for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j ) {
1133                 if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j])) {
1134                     tmp = vp8hwdReadBits(bit_ctx, 7);
1135                     if ( tmp )
1136                         tmp = tmp << 1;
1137                     else
1138                         tmp = 1;
1139                     p->entropy.probMvContext[i][j] = tmp;
1140                 }
1141             }
1142         }
1143     }
1144     if (bit_ctx->strmError) {
1145         FUN_T("FUN_OUT");
1146         return MPP_ERR_PROTOL;
1147     }
1148 
1149     FUN_T("FUN_OUT");
1150     return MPP_OK;
1151 }
1152 
1153 static MPP_RET
vp8hwdSetPartitionOffsets(VP8DParserContext_t * p,RK_U8 * stream,RK_U32 len)1154 vp8hwdSetPartitionOffsets(VP8DParserContext_t *p, RK_U8 *stream, RK_U32 len)
1155 {
1156     RK_U32 i = 0;
1157     RK_U32 offset = 0;
1158     RK_U32 baseOffset;
1159     RK_U32 extraBytesPacked = 0;
1160 
1161     FUN_T("FUN_IN");
1162     if (p->decMode == VP8HWD_VP8 && p->keyFrame)
1163         extraBytesPacked += 7;
1164 
1165     stream += p->frameTagSize;
1166 
1167     baseOffset = p->frameTagSize + p->offsetToDctParts
1168                  + 3 * ( (1 << p->nbrDctPartitions) - 1);
1169 
1170     stream += p->offsetToDctParts + extraBytesPacked;
1171     for ( i = 0 ; i < (RK_U32)(1 << p->nbrDctPartitions) - 1 ; ++i ) {
1172         RK_U32  tmp;
1173 
1174         p->dctPartitionOffsets[i] = baseOffset + offset;
1175         tmp = stream[0] | (stream[1] << 8) | (stream[2] << 16);
1176         offset += tmp;
1177         stream += 3;
1178     }
1179     p->dctPartitionOffsets[i] = baseOffset + offset;
1180 
1181     return (p->dctPartitionOffsets[i] < len ? MPP_OK : MPP_ERR_STREAM);
1182 }
1183 
1184 static MPP_RET
decoder_frame_header(VP8DParserContext_t * p,RK_U8 * pbase,RK_U32 size)1185 decoder_frame_header(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size)
1186 {
1187     MPP_RET ret;
1188 
1189     FUN_T("FUN_IN");
1190     p->keyFrame = !(pbase[0] & 1);
1191     p->vpVersion = (pbase[0] >> 1) & 7;
1192     p->showFrame = 1;
1193     if (p->keyFrame && !p->needKeyFrame) {
1194         p->needKeyFrame = 1;
1195     } else {
1196         if (!p->needKeyFrame) {
1197             mpp_err("no found key frame");
1198             return MPP_NOK;
1199         }
1200     }
1201     if (p->decMode == VP8HWD_VP7) {
1202         p->offsetToDctParts = (pbase[0] >> 4) | (pbase[1] << 4) | (pbase[2] << 12);
1203         p->frameTagSize = p->vpVersion >= 1 ? 3 : 4;
1204     } else {
1205         p->offsetToDctParts = (pbase[0] >> 5) | (pbase[1] << 3) | (pbase[2] << 11);
1206 #if 0
1207         mpp_log("offsetToDctParts %d pbase[0] = 0x%x pbase[1] = 0x%x pbase[2] = 0x%x ",
1208                 p->offsetToDctParts, pbase[0], pbase[1], pbase[2]);
1209 #endif
1210         p->showFrame = (pbase[0] >> 4) & 1;
1211         p->frameTagSize = 3;
1212     }
1213     pbase += p->frameTagSize;
1214     size -= p->frameTagSize;
1215     if (p->keyFrame)
1216         vp8hwdResetProbs(p);
1217     //mpp_log_f("p->decMode = %d", p->decMode);
1218     if (p->decMode == VP8HWD_VP8) {
1219         ret = vp8_header_parser(p, pbase, size);
1220     }  else {
1221         ret = vp7_header_parser(p, pbase, size);
1222     }
1223     if (ret != MPP_OK) {
1224         return ret;
1225     }
1226     return MPP_OK;
1227 }
1228 
1229 #define IVF_HDR_BYTES       32
1230 #define IVF_FRM_BYTES       12
1231 
write_ivf_header(VP8DParserContext_t * ctx,FILE * fp)1232 static void write_ivf_header(VP8DParserContext_t *ctx, FILE *fp)
1233 {
1234     RK_U8 data[IVF_HDR_BYTES] = {0};
1235 
1236     data[0] = 'D';
1237     data[1] = 'K';
1238     data[2] = 'I';
1239     data[3] = 'F';
1240 
1241     data[6] = 32;
1242 
1243     data[8] = 'V';
1244     data[9] = 'P';
1245     data[10] = '8';
1246     data[11] = '0';
1247 
1248     data[12] = ctx->width & 0xff;
1249     data[13] = (ctx->width >> 8) & 0xff;
1250     data[14] = ctx->height & 0xff;
1251     data[15] = (ctx->height >> 8) & 0xff;
1252 
1253     data[16] = 30;
1254     data[17] = data[18] = data[19] = 0;
1255 
1256     data[20] = 1;
1257     data[21] = data[22] = data[23] = 0;
1258 
1259     data[24] = data[25] = data[26] = data[27] = 0xff;
1260 
1261     fwrite(data, IVF_HDR_BYTES, 1, fp);
1262 }
1263 
write_ivf_frame(FILE * fp,RK_U32 frame_size,RK_U64 frame_cnt)1264 static void write_ivf_frame(FILE *fp, RK_U32 frame_size, RK_U64 frame_cnt)
1265 {
1266     RK_U8 data[IVF_FRM_BYTES];
1267 
1268     data[0] = frame_size & 0xff;
1269     data[1] = (frame_size >> 8) & 0xff;
1270     data[2] = (frame_size >> 16) & 0xff;
1271     data[3] = (frame_size >> 24) & 0xff;
1272 
1273     data[4]  = frame_cnt & 0xff;
1274     data[5]  = (frame_cnt >> 8) & 0xff;
1275     data[6]  = (frame_cnt >> 16) & 0xff;
1276     data[7]  = (frame_cnt >> 24) & 0xff;
1277     data[8]  = (frame_cnt >> 32) & 0xff;
1278     data[9]  = (frame_cnt >> 40) & 0xff;
1279     data[10] = (frame_cnt >> 48) & 0xff;
1280     data[11] = (frame_cnt >> 56) & 0xff;
1281 
1282     fwrite(data, IVF_FRM_BYTES, 1, fp);
1283 }
1284 
vp8d_parser_parse(void * ctx,HalDecTask * in_task)1285 MPP_RET vp8d_parser_parse(void *ctx, HalDecTask *in_task)
1286 {
1287     MPP_RET ret = MPP_OK;
1288     VP8DContext *c = (VP8DContext *)ctx;
1289     VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx;
1290     FUN_T("FUN_IN");
1291 
1292     ret = decoder_frame_header(p, p->bitstream_sw_buf, p->stream_size);
1293 
1294     if (MPP_OK != ret) {
1295         mpp_err("decoder_frame_header err ret %d", ret);
1296         FUN_T("FUN_OUT");
1297         return ret;
1298     }
1299 
1300     vp8hwdSetPartitionOffsets(p, p->bitstream_sw_buf, p->stream_size);
1301 
1302     ret = vp8d_alloc_frame(p);
1303     if (MPP_OK != ret) {
1304         mpp_err("vp8d_alloc_frame err ret %d", ret);
1305         FUN_T("FUN_OUT");
1306         return ret;
1307     }
1308 
1309     vp8d_convert_to_syntx(p, in_task);
1310     /* Rollback entropy probabilities if refresh is not set */
1311     if (p->refreshEntropyProbs == 0) {
1312         memcpy((void*)&p->entropy, (void*)&p->entropyLast,
1313                (unsigned long)sizeof(vp8EntropyProbs_t));
1314         memcpy((void*)p->vp7ScanOrder, (void*)p->vp7PrevScanOrder,
1315                (unsigned long)sizeof(p->vp7ScanOrder));
1316     }
1317     in_task->syntax.data = (void *)p->dxva_ctx;
1318     in_task->syntax.number = 1;
1319     in_task->output = p->frame_out->slot_index;
1320     in_task->valid = 1;
1321     if (p->eos) {
1322         in_task->flags.eos = p->eos;
1323     }
1324     vp8d_ref_update(p);
1325 
1326     if (vp8d_debug & VP8D_DBG_DUMP_STREAM) {
1327         if (!p->stream_fp) {
1328             char name[256];
1329 
1330             sprintf(name, "/data/video/mpp_dec_vp8_%d.bin", getpid());
1331             p->stream_fp = fopen(name, "wb");
1332         }
1333         if (p->stream_fp) {
1334             if (!p->ivf_header_flag) {
1335                 write_ivf_header(p, p->stream_fp);
1336                 p->ivf_header_flag = 1;
1337             }
1338             write_ivf_frame(p->stream_fp, p->stream_size, p->frame_cnt);
1339             fwrite(p->bitstream_sw_buf, 1, p->stream_size, p->stream_fp);
1340             fflush(p->stream_fp);
1341         }
1342     }
1343     p->frame_cnt++;
1344 
1345     FUN_T("FUN_OUT");
1346     return ret;
1347 }
1348 
vp8d_parser_callback(void * ctx,void * hal_info)1349 MPP_RET vp8d_parser_callback(void *ctx, void *hal_info)
1350 {
1351     MPP_RET ret = MPP_OK;
1352     FUN_T("FUN_IN");
1353     (void)ctx;
1354     (void)hal_info;
1355     FUN_T("FUN_OUT");
1356     return ret;
1357 }
1358