Beispiel #1
0
int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, int deblock_level,  int noise_level, int flags)
{
    int ret = -1;
    VP8D_COMP *pbi = (VP8D_COMP *) ptr;

    if (pbi->ready_for_new_data == 1)
        return ret;

    // ie no raw frame to show!!!
    if (pbi->common.show_frame == 0)
        return ret;

    pbi->ready_for_new_data = 1;
    *time_stamp = pbi->last_time_stamp;
    *time_end_stamp = 0;

    sd->clrtype = pbi->common.clr_type;
#if CONFIG_POSTPROC
    ret = vp8_post_proc_frame(&pbi->common, sd, deblock_level, noise_level, flags);
#else

    if (pbi->common.frame_to_show)
    {
        *sd = *pbi->common.frame_to_show;
        sd->y_width = pbi->common.Width;
        sd->y_height = pbi->common.Height;
        sd->uv_height = pbi->common.Height / 2;
        ret = 0;
    }
    else
    {
        ret = -1;
    }

#endif //!CONFIG_POSTPROC
    vp8_clear_system_state();
    return ret;
}
Beispiel #2
0
int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags)
{
    int ret = -1;

    if (pbi->ready_for_new_data == 1)
        return ret;

    /* ie no raw frame to show!!! */
    if (pbi->common.show_frame == 0)
        return ret;

    pbi->ready_for_new_data = 1;
    *time_stamp = pbi->last_time_stamp;
    *time_end_stamp = 0;

    sd->clrtype = pbi->common.clr_type;
#if CONFIG_POSTPROC
    ret = vp8_post_proc_frame(&pbi->common, sd, flags);
#else

    if (pbi->common.frame_to_show)
    {
        *sd = *pbi->common.frame_to_show;
        sd->y_width = pbi->common.Width;
        sd->y_height = pbi->common.Height;
        sd->uv_height = pbi->common.Height / 2;
        ret = 0;
    }
    else
    {
        ret = -1;
    }

#endif /*!CONFIG_POSTPROC*/
    vp8_clear_system_state();
    return ret;
}
Beispiel #3
0
int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size,
                                  const uint8_t *source,
                                  int64_t time_stamp,
                                  uint8_t dry_run)
{
#if HAVE_NEON
    int64_t dx_store_reg[8];
#endif
    VP8_COMMON *cm = &pbi->common;
    int retcode = -1;

    pbi->common.error.error_code = VPX_CODEC_OK;

    retcode = check_fragments_for_errors(pbi);
    if(retcode <= 0)
        return retcode;

#if HAVE_NEON
#if CONFIG_RUNTIME_CPU_DETECT
    if (cm->cpu_caps & HAS_NEON)
#endif
    {
        vp8_push_neon(dx_store_reg);
    }
#endif

    cm->new_fb_idx = get_free_fb (cm);

    /* setup reference frames for vp8_decode_frame */
    pbi->dec_fb_ref[INTRA_FRAME]  = &cm->yv12_fb[cm->new_fb_idx];
    pbi->dec_fb_ref[LAST_FRAME]   = &cm->yv12_fb[cm->lst_fb_idx];
    pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx];
    pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx];

    if (setjmp(pbi->common.error.jmp))
    {
       /* We do not know if the missing frame(s) was supposed to update
        * any of the reference buffers, but we act conservative and
        * mark only the last buffer as corrupted.
        */
        cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;

        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;

        goto decode_exit;
    }

    pbi->common.error.setjmp = 1;

    retcode = vp8_decode_frame(pbi, dry_run);

    if (retcode < 0)
    {
        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;

        pbi->common.error.error_code = VPX_CODEC_ERROR;
        goto decode_exit;
    }

    if (swap_frame_buffers (cm))
    {
        pbi->common.error.error_code = VPX_CODEC_ERROR;
        goto decode_exit;
    }

    vp8_clear_system_state();

    if (cm->show_frame)
    {
        cm->current_video_frame++;
        cm->show_frame_mi = cm->mi;
    }

    #if CONFIG_ERROR_CONCEALMENT
    /* swap the mode infos to storage for future error concealment */
    if (pbi->ec_enabled && pbi->common.prev_mi)
    {
        MODE_INFO* tmp = pbi->common.prev_mi;
        int row, col;
        pbi->common.prev_mi = pbi->common.mi;
        pbi->common.mi = tmp;

        /* Propagate the segment_ids to the next frame */
        for (row = 0; row < pbi->common.mb_rows; ++row)
        {
            for (col = 0; col < pbi->common.mb_cols; ++col)
            {
                const int i = row*pbi->common.mode_info_stride + col;
                pbi->common.mi[i].mbmi.segment_id =
                        pbi->common.prev_mi[i].mbmi.segment_id;
            }
        }
    }
#endif

    pbi->ready_for_new_data = 0;
    pbi->last_time_stamp = time_stamp;

decode_exit:
#if HAVE_NEON
#if CONFIG_RUNTIME_CPU_DETECT
    if (cm->cpu_caps & HAS_NEON)
#endif
    {
        vp8_pop_neon(dx_store_reg);
    }
#endif

    pbi->common.error.setjmp = 0;
    return retcode;
}
Beispiel #4
0
int onyx_blit
(
    XIMAGE_HANDLE src,
    VSCREEN_HANDLE v_screen,
    DXV_YUV_BUFFER_CONFIG *frame_buffer,
    int x,
    int y
)
{
    VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    VP8D_COMP *pbi;
    VP8_COMMON *common = tab->common;
    pbi = tab->my_pbi;

    if (v_screen) /* if there is a v_screen, blit to it */
    {
        unsigned char *ptr_scrn;
        int this_pitch, vs_height, vs_width;
        unsigned int start_tick, stop_tick;

        vpxdxv_get_vscreen_attributes(v_screen, (void **)&ptr_scrn,  &vs_width, &vs_height, &this_pitch);

        if (ptr_scrn)
        {
            int w, h;

            int p_size;
            int view_x, view_y, view_w;
            int hs, hr, vs, vr;
            int neww, newh;
            int cw, ch;
            int microseconds_available = (int)(1000000 / 30);

            microseconds_available = microseconds_available * tab->cpu_free / 100;

            if (pbi)
            {
                microseconds_available -= pbi->decode_microseconds;

                if (tab->cpu_free == 0)
                    microseconds_available = INT_MAX;

                if (tab->post_proc2time == 0)
                    tab->post_proc2time = pbi->decode_microseconds * 1 / 2;

                if (tab->post_proc4time == 0)
                    tab->post_proc4time = pbi->decode_microseconds;
            }


            if (tab->ppcount == 0)
            {
                tab->post_proc2time = 0;
                tab->post_proc4time = 0;
                tab->ppcount = 64;
            }
            else
            {
                tab->ppcount --;
            }

            vpxdxv_get_vscreen_view(v_screen, &view_x, &view_y, &view_w, NULL);

            Scale2Ratio(common->horiz_scale, &hr, &hs);
            Scale2Ratio(common->vert_scale, &vr, &vs);

            if (tab->postproc && tab->passed_in_buffer == 0)
            {
                int show_text = 0;

                unsigned char message[512];

                int pp = tab->postproc;
                int q = (tab->avgq + 4) / 8;
                int noise = 0;

                vp8_clear_system_state();

                if (pp >= 1000)
                {
                    pp -= 1000;
                    noise = pp / 100;
                    pp = pp - noise * 100;
                }

                if (pp >= 300)
                {
                    pp -= 300;
                    show_text = 3;
                }
                else if (pp >= 200)
                {
                    pp -= 200;
                    show_text = 2;
                }
                else if (pp >= 100)
                {
                    pp -= 100;
                    show_text = 1;
                }

                if (pbi && (pbi->mb.segmentation_enabled & SEGMENT_PF) && tab->deinterlace)
                {
                    de_interlace(common->frame_to_show->y_buffer, common->post_proc_buffer.y_buffer,
                                 common->post_proc_buffer.y_width, common->post_proc_buffer.y_height,
                                 common->post_proc_buffer.y_stride);

                    de_interlace(common->frame_to_show->u_buffer, common->post_proc_buffer.u_buffer,
                                 common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height,
                                 common->post_proc_buffer.uv_stride);
                    de_interlace(common->frame_to_show->v_buffer, common->post_proc_buffer.v_buffer,
                                 common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height,
                                 common->post_proc_buffer.uv_stride);
                }
                else
                {
                    if (pp >= 10 && pp <= 20)
                    {
                        q = q + (pp - 15) * 10;

                        if (q < 0)
                            q = 0;
                    }

                    start_tick = vp8_get_high_res_timer_tick();

                    if (pp > 3 && tab->post_proc4time < microseconds_available)
                    {
                        vp8_deblock_and_de_macro_block(common->frame_to_show, &common->post_proc_buffer, q, 1, 0);

                        stop_tick = vp8_get_high_res_timer_tick();

                        if (pbi)
                            tab->post_proc4time = vp8_get_time_in_micro_sec(start_tick, stop_tick);
                    }

                    else if (pp > 0 && tab->post_proc2time < microseconds_available)
                    {
                        vp8_deblock(common->frame_to_show, &common->post_proc_buffer, q , 1,  0);
                        stop_tick = vp8_get_high_res_timer_tick();

                        if (pbi)
                            tab->post_proc2time = vp8_get_time_in_micro_sec(start_tick, stop_tick);
                    }
                    else
                    {
                        vp8_yv12_copy_frame(common->frame_to_show, &common->post_proc_buffer);
                    }

                }

                vp8_clear_system_state();

                if (tab->add_noise == 1)
                {

                    vp8_plane_add_noise(common->post_proc_buffer.y_buffer,
                                        common->post_proc_buffer.y_width, common->post_proc_buffer.y_height,
                                        common->post_proc_buffer.y_stride, 63 - q, noise);
                }


                if (show_text == 1)
                {
#ifdef PACKET_TESTING
                    {
                        VP8_HEADER *oh2 = (VP8_HEADER *) pbi->Source;
                        sprintf(message, "%8d %d%d%d%d%d size:%d\n",
                        oh2->frame_number ,
                        oh2->update_gold  ,
                        oh2->update_last  ,
                        oh2->uses_gold    ,
                        oh2->uses_last    ,
                        oh2->type,
                        vpxdxv_get_ximage_csize(src));
                    }
#else
                    sprintf(message, "F:%1ldG:%1ldQ:%3ldF:%3ld,%3ldP:%d_s:%6ld,N:%d,",
                            (common->frame_type == KEY_FRAME),
                            common->refresh_golden_frame,
                            common->base_qindex,
                            common->filter_level,
                            q,
                            tab->postproc,
                            vpxdxv_get_ximage_csize(src), noise);
#endif

                    vp8_blit_text(message, common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_stride);

                }
                else if (show_text == 2)
                {
                    int i, j;
                    unsigned char *y_ptr;
                    YV12_BUFFER_CONFIG *post = &common->post_proc_buffer;
                    int mb_rows = post->y_height >> 4;
                    int mb_cols = post->y_width  >> 4;
                    int mb_index = 0;
                    MODE_INFO *mi = common->mi;

                    y_ptr = post->y_buffer + 4 * post->y_stride + 4;

                    // vp8_filter each macro block
                    for (i = 0; i < mb_rows; i++)
                    {
                        for (j = 0; j < mb_cols; j++)
                        {
                            char zz[4];

                            if (pp == 4)
                                sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
                            else
                                sprintf(zz, "%c", mi[mb_index].mbmi.ref_frame + 'a');

                            vp8_blit_text(zz, y_ptr, post->y_stride);
                            mb_index ++;
                            y_ptr += 16;
                        }

                        mb_index ++; //border
                        y_ptr += post->y_stride  * 16 - post->y_width;

                    }
                }
                else if (show_text == 3)
                {
                    int i, j;
                    unsigned char *y_ptr;
                    YV12_BUFFER_CONFIG *post = &common->post_proc_buffer;
                    int mb_rows = post->y_height >> 4;
                    int mb_cols = post->y_width  >> 4;
                    int mb_index = 0;
                    MODE_INFO *mi = common->mi;

                    y_ptr = post->y_buffer + 4 * post->y_stride + 4;

                    // vp8_filter each macro block
                    for (i = 0; i < mb_rows; i++)
                    {
                        for (j = 0; j < mb_cols; j++)
                        {
                            char zz[4];

                            if (j == 0)
                                sprintf(zz, "%c", '0' + i % 10);
                            else
                                sprintf(zz, "%c", '0' + j % 10);

                            vp8_blit_text(zz, y_ptr, post->y_stride);
                            mb_index ++;
                            y_ptr += 16;
                        }

                        y_ptr += post->y_stride  * 16 - post->y_width;

                    }
                }
Beispiel #5
0
int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
{
    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
    VP8_COMMON *cm = &pbi->common;
    int retcode = 0;

    struct vpx_usec_timer timer;

//  if(pbi->ready_for_new_data == 0)
//      return -1;

    if (ptr == 0)
    {
        return -1;
    }

    pbi->common.error.error_code = VPX_CODEC_OK;

    if (setjmp(pbi->common.error.jmp))
    {
        pbi->common.error.setjmp = 0;
        return -1;
    }

    pbi->common.error.setjmp = 1;

#if HAVE_ARMV7
    vp8_push_neon(dx_store_reg);
#endif

    vpx_usec_timer_start(&timer);

    //cm->current_video_frame++;
    pbi->Source = source;
    pbi->source_sz = size;

    retcode = vp8_decode_frame(pbi);

    if (retcode < 0)
    {
#if HAVE_ARMV7
        vp8_pop_neon(dx_store_reg);
#endif
        pbi->common.error.error_code = VPX_CODEC_ERROR;
        pbi->common.error.setjmp = 0;
        return retcode;
    }

    // Update the GF useage maps.
    vp8_update_gf_useage_maps(cm, &pbi->mb);

    if (pbi->b_multithreaded_lf && pbi->common.filter_level != 0)
        vp8_stop_lfthread(pbi);

    if (cm->refresh_last_frame)
    {
        vp8_swap_yv12_buffer(&cm->last_frame, &cm->new_frame);

        cm->frame_to_show = &cm->last_frame;
    }
    else
    {
        cm->frame_to_show = &cm->new_frame;
    }

    if (!pbi->b_multithreaded_lf)
    {
        struct vpx_usec_timer lpftimer;
        vpx_usec_timer_start(&lpftimer);
        // Apply the loop filter if appropriate.

        if (cm->filter_level > 0)
        {
            vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
            cm->last_frame_type = cm->frame_type;
            cm->last_filter_type = cm->filter_type;
            cm->last_sharpness_level = cm->sharpness_level;

        }

        vpx_usec_timer_mark(&lpftimer);
        pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
    }

    vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);

#if 0
    // DEBUG code
    //vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
    if (cm->current_video_frame <= 5)
        write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
#endif

    // If any buffer copy / swaping is signalled it should be done here.
    if (cm->copy_buffer_to_arf)
    {
        if (cm->copy_buffer_to_arf == 1)
        {
            if (cm->refresh_last_frame)
                vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->alt_ref_frame);
            else
                vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->alt_ref_frame);
        }
        else if (cm->copy_buffer_to_arf == 2)
            vp8_yv12_copy_frame_ptr(&cm->golden_frame, &cm->alt_ref_frame);
    }

    if (cm->copy_buffer_to_gf)
    {
        if (cm->copy_buffer_to_gf == 1)
        {
            if (cm->refresh_last_frame)
                vp8_yv12_copy_frame_ptr(&cm->new_frame, &cm->golden_frame);
            else
                vp8_yv12_copy_frame_ptr(&cm->last_frame, &cm->golden_frame);
        }
        else if (cm->copy_buffer_to_gf == 2)
            vp8_yv12_copy_frame_ptr(&cm->alt_ref_frame, &cm->golden_frame);
    }

    // Should the golden or alternate reference frame be refreshed?
    if (cm->refresh_golden_frame || cm->refresh_alt_ref_frame)
    {
        if (cm->refresh_golden_frame)
            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->golden_frame);

        if (cm->refresh_alt_ref_frame)
            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->alt_ref_frame);

        //vpx_log("Decoder: recovery frame received \n");

        // Update data structures that monitors GF useage
        vpx_memset(cm->gf_active_flags, 1, (cm->mb_rows * cm->mb_cols));
        cm->gf_active_count = cm->mb_rows * cm->mb_cols;
    }

    vp8_clear_system_state();

    vpx_usec_timer_mark(&timer);
    pbi->decode_microseconds = vpx_usec_timer_elapsed(&timer);

    pbi->time_decoding += pbi->decode_microseconds;

//  vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);

    if (cm->show_frame)
        cm->current_video_frame++;

    pbi->ready_for_new_data = 0;
    pbi->last_time_stamp = time_stamp;

#if 0
    {
        int i;
        INT64 earliest_time = pbi->dr[0].time_stamp;
        INT64 latest_time = pbi->dr[0].time_stamp;
        INT64 time_diff = 0;
        int bytes = 0;

        pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
        pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;

        for (i = 0; i < 16; i++)
        {

            bytes += pbi->dr[i].size;

            if (pbi->dr[i].time_stamp < earliest_time)
                earliest_time = pbi->dr[i].time_stamp;

            if (pbi->dr[i].time_stamp > latest_time)
                latest_time = pbi->dr[i].time_stamp;
        }

        time_diff = latest_time - earliest_time;

        if (time_diff > 0)
        {
            pbi->common.bitrate = 80000.00 * bytes / time_diff  ;
            pbi->common.framerate = 160000000.00 / time_diff ;
        }

    }
#endif

#if HAVE_ARMV7
    vp8_pop_neon(dx_store_reg);
#endif
    pbi->common.error.setjmp = 0;
    return retcode;
}
Beispiel #6
0
static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t  *ctx,
                                  const uint8_t         *data,
                                  unsigned int            data_sz,
                                  void                    *user_priv,
                                  long                    deadline)
{
    vpx_codec_err_t res = VPX_CODEC_OK;
    unsigned int resolution_change = 0;
    unsigned int w, h;

    if (!ctx->fragments.enabled && (data == NULL && data_sz == 0))
    {
        return 0;
    }

    /* Update the input fragment data */
    if(update_fragments(ctx, data, data_sz, &res) <= 0)
        return res;

    /* Determine the stream parameters. Note that we rely on peek_si to
     * validate that we have a buffer that does not wrap around the top
     * of the heap.
     */
    w = ctx->si.w;
    h = ctx->si.h;

    res = vp8_peek_si_internal(ctx->fragments.ptrs[0], ctx->fragments.sizes[0],
                               &ctx->si, ctx->decrypt_cb, ctx->decrypt_state);

    if((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf)
    {
        /* the peek function returns an error for non keyframes, however for
         * this case, it is not an error */
        res = VPX_CODEC_OK;
    }

    if(!ctx->decoder_init && !ctx->si.is_kf)
        res = VPX_CODEC_UNSUP_BITSTREAM;

    if ((ctx->si.h != h) || (ctx->si.w != w))
        resolution_change = 1;

    /* Initialize the decoder instance on the first frame*/
    if (!res && !ctx->decoder_init)
    {
      VP8D_CONFIG oxcf;

      oxcf.Width = ctx->si.w;
      oxcf.Height = ctx->si.h;
      oxcf.Version = 9;
      oxcf.postprocess = 0;
      oxcf.max_threads = ctx->cfg.threads;
      oxcf.error_concealment =
          (ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT);

      /* If postprocessing was enabled by the application and a
       * configuration has not been provided, default it.
       */
       if (!ctx->postproc_cfg_set
           && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
         ctx->postproc_cfg.post_proc_flag =
             VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE;
         ctx->postproc_cfg.deblocking_level = 4;
         ctx->postproc_cfg.noise_level = 0;
       }

       res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf);
       ctx->decoder_init = 1;
    }

    /* Set these even if already initialized.  The caller may have changed the
     * decrypt config between frames.
     */
    if (ctx->decoder_init) {
      ctx->yv12_frame_buffers.pbi[0]->decrypt_cb = ctx->decrypt_cb;
      ctx->yv12_frame_buffers.pbi[0]->decrypt_state = ctx->decrypt_state;
    }

    if (!res)
    {
        VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0];
        if (resolution_change)
        {
            VP8_COMMON *const pc = & pbi->common;
            MACROBLOCKD *const xd  = & pbi->mb;
#if CONFIG_MULTITHREAD
            int i;
#endif
            pc->Width = ctx->si.w;
            pc->Height = ctx->si.h;
            {
                int prev_mb_rows = pc->mb_rows;

                if (setjmp(pbi->common.error.jmp))
                {
                    pbi->common.error.setjmp = 0;
                    vp8_clear_system_state();
                    /* same return value as used in vp8dx_receive_compressed_data */
                    return -1;
                }

                pbi->common.error.setjmp = 1;

                if (pc->Width <= 0)
                {
                    pc->Width = w;
                    vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                                       "Invalid frame width");
                }

                if (pc->Height <= 0)
                {
                    pc->Height = h;
                    vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                                       "Invalid frame height");
                }

                if (vp8_alloc_frame_buffers(pc, pc->Width, pc->Height))
                    vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                       "Failed to allocate frame buffers");

                xd->pre = pc->yv12_fb[pc->lst_fb_idx];
                xd->dst = pc->yv12_fb[pc->new_fb_idx];

#if CONFIG_MULTITHREAD
                for (i = 0; i < pbi->allocated_decoding_thread_count; i++)
                {
                    pbi->mb_row_di[i].mbd.dst = pc->yv12_fb[pc->new_fb_idx];
                    vp8_build_block_doffsets(&pbi->mb_row_di[i].mbd);
                }
#endif
                vp8_build_block_doffsets(&pbi->mb);

                /* allocate memory for last frame MODE_INFO array */
#if CONFIG_ERROR_CONCEALMENT

                if (pbi->ec_enabled)
                {
                    /* old prev_mip was released by vp8_de_alloc_frame_buffers()
                     * called in vp8_alloc_frame_buffers() */
                    pc->prev_mip = vpx_calloc(
                                       (pc->mb_cols + 1) * (pc->mb_rows + 1),
                                       sizeof(MODE_INFO));

                    if (!pc->prev_mip)
                    {
                        vp8_de_alloc_frame_buffers(pc);
                        vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                           "Failed to allocate"
                                           "last frame MODE_INFO array");
                    }

                    pc->prev_mi = pc->prev_mip + pc->mode_info_stride + 1;

                    if (vp8_alloc_overlap_lists(pbi))
                        vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                                           "Failed to allocate overlap lists "
                                           "for error concealment");
                }

#endif

#if CONFIG_MULTITHREAD
                if (pbi->b_multithreaded_rd)
                    vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows);
#else
                (void)prev_mb_rows;
#endif
            }

            pbi->common.error.setjmp = 0;

            /* required to get past the first get_free_fb() call */
            pbi->common.fb_idx_ref_cnt[0] = 0;
        }

        /* update the pbi fragment data */
        pbi->fragments = ctx->fragments;

        ctx->user_priv = user_priv;
        if (vp8dx_receive_compressed_data(pbi, data_sz, data, deadline))
        {
            res = update_error_state(ctx, &pbi->common.error);
        }

        /* get ready for the next series of fragments */
        ctx->fragments.count = 0;
    }

    return res;
}
int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
{
#if HAVE_ARMV7
    INT64 dx_store_reg[8];
#endif
    VP8D_COMP *pbi = (VP8D_COMP *) ptr;
    VP8_COMMON *cm = &pbi->common;
    int retcode = 0;
    struct vpx_usec_timer timer;

    /*if(pbi->ready_for_new_data == 0)
        return -1;*/

    if (ptr == 0)
    {
        return -1;
    }

    pbi->common.error.error_code = VPX_CODEC_OK;

    if (size == 0)
    {
       /* This is used to signal that we are missing frames.
        * We do not know if the missing frame(s) was supposed to update
        * any of the reference buffers, but we act conservative and
        * mark only the last buffer as corrupted.
        */
        cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;

        /* Signal that we have no frame to show. */
        cm->show_frame = 0;

        /* Nothing more to do. */
        return 0;
    }


#if HAVE_ARMV7
#if CONFIG_RUNTIME_CPU_DETECT
    if (cm->rtcd.flags & HAS_NEON)
#endif
    {
        vp8_push_neon(dx_store_reg);
    }
#endif

    cm->new_fb_idx = get_free_fb (cm);

    if (setjmp(pbi->common.error.jmp))
    {
#if HAVE_ARMV7
#if CONFIG_RUNTIME_CPU_DETECT
        if (cm->rtcd.flags & HAS_NEON)
#endif
        {
            vp8_pop_neon(dx_store_reg);
        }
#endif
        pbi->common.error.setjmp = 0;

       /* We do not know if the missing frame(s) was supposed to update
        * any of the reference buffers, but we act conservative and
        * mark only the last buffer as corrupted.
        */
        cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;

        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
        return -1;
    }

    pbi->common.error.setjmp = 1;

    vpx_usec_timer_start(&timer);

    /*cm->current_video_frame++;*/
    pbi->Source = source;
    pbi->source_sz = size;

    retcode = vp8_decode_frame(pbi);

    if (retcode < 0)
    {
#if HAVE_ARMV7
#if CONFIG_RUNTIME_CPU_DETECT
        if (cm->rtcd.flags & HAS_NEON)
#endif
        {
            vp8_pop_neon(dx_store_reg);
        }
#endif
        pbi->common.error.error_code = VPX_CODEC_ERROR;
        pbi->common.error.setjmp = 0;
        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
        return retcode;
    }

#if CONFIG_MULTITHREAD
    if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION)
    {
        if (swap_frame_buffers (cm))
        {
#if HAVE_ARMV7
#if CONFIG_RUNTIME_CPU_DETECT
            if (cm->rtcd.flags & HAS_NEON)
#endif
            {
                vp8_pop_neon(dx_store_reg);
            }
#endif
            pbi->common.error.error_code = VPX_CODEC_ERROR;
            pbi->common.error.setjmp = 0;
            return -1;
        }
    } else
#endif
    {
        if (swap_frame_buffers (cm))
        {
#if HAVE_ARMV7
#if CONFIG_RUNTIME_CPU_DETECT
            if (cm->rtcd.flags & HAS_NEON)
#endif
            {
                vp8_pop_neon(dx_store_reg);
            }
#endif
            pbi->common.error.error_code = VPX_CODEC_ERROR;
            pbi->common.error.setjmp = 0;
            return -1;
        }

        if(pbi->common.filter_level)
        {
            struct vpx_usec_timer lpftimer;
            vpx_usec_timer_start(&lpftimer);
            /* Apply the loop filter if appropriate. */

            vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);

            vpx_usec_timer_mark(&lpftimer);
            pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);

            cm->last_frame_type = cm->frame_type;
            cm->last_filter_type = cm->filter_type;
            cm->last_sharpness_level = cm->sharpness_level;
        }
        vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
    }


    vp8_clear_system_state();

    vpx_usec_timer_mark(&timer);
    pbi->decode_microseconds = vpx_usec_timer_elapsed(&timer);

    pbi->time_decoding += pbi->decode_microseconds;

    /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/

    if (cm->show_frame)
        cm->current_video_frame++;

    pbi->ready_for_new_data = 0;
    pbi->last_time_stamp = time_stamp;

#if 0
    {
        int i;
        INT64 earliest_time = pbi->dr[0].time_stamp;
        INT64 latest_time = pbi->dr[0].time_stamp;
        INT64 time_diff = 0;
        int bytes = 0;

        pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
        pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;

        for (i = 0; i < 16; i++)
        {

            bytes += pbi->dr[i].size;

            if (pbi->dr[i].time_stamp < earliest_time)
                earliest_time = pbi->dr[i].time_stamp;

            if (pbi->dr[i].time_stamp > latest_time)
                latest_time = pbi->dr[i].time_stamp;
        }

        time_diff = latest_time - earliest_time;

        if (time_diff > 0)
        {
            pbi->common.bitrate = 80000.00 * bytes / time_diff  ;
            pbi->common.framerate = 160000000.00 / time_diff ;
        }

    }
#endif

#if HAVE_ARMV7
#if CONFIG_RUNTIME_CPU_DETECT
    if (cm->rtcd.flags & HAS_NEON)
#endif
    {
        vp8_pop_neon(dx_store_reg);
    }
#endif
    pbi->common.error.setjmp = 0;
    return retcode;
}