Exemplo n.º 1
0
// for android neon accelerate
status_t FFRender::render_neon(AVFrame* frame)
{
#if !defined(__ANDROID__) || defined(__i386__) || defined(__x86_64__)
    return ERROR;
#else
    void* surfacePixels = NULL;
    if (Surface_getPixels(mNativeWindow, &mSurfaceWidth, &mSurfaceHeight, &mSurfaceStride, &surfacePixels) != OK)
        return ERROR;

    int64_t begin_scale = getNowMs();

    //Convert format
    switch(mFrameFormat)
    {
    case AV_PIX_FMT_YUV420P:
    {
        if (mDoOnce) {
            LOGI("frame->data: %p, %p, %p", frame->data[0], frame->data[1], frame->data[2]); //((((int32_t)frame->data[0])+0x20)&0xffffffe0)
            LOGI("frame->linesize: %d,%d,%d", frame->linesize[0], frame->linesize[1], frame->linesize[2]);
            LOGI("frame->width: %d, frame->height: %d", frame->width, frame->height);
            LOGI("mSurface width %d, height %d, stride %d", mSurfaceWidth, mSurfaceHeight, mSurfaceStride);
            mDoOnce = false;
        }

        // 2015.4.24 guoliangma modify mSurfaceStride to mSurfaceWidth
        // fix crash when play some small res clip then play big res clip
        if ((int)mSurfaceWidth >= frame->width && (int)mSurfaceHeight >= frame->height) {
#ifdef __arm__
#ifdef RENDER_RGB565
            /*yuv420_2_rgb565((uint8_t *)surfacePixels,
            	frame->data[0], frame->data[1], frame->data[2],
            	frame->width, frame->height, // picture width and height
            	frame->linesize[0], //Y span/pitch
            	frame->linesize[1], //UV span/pitch //frame->linesize[1]
            	mSurfaceStride<<1, //bitmap span/pitch
            	yuv2rgb565_table,
            	0);*/
            ConvertYCbCrToRGB565(
                frame->data[0], frame->data[1], frame->data[2],
                (uint8_t*)surfacePixels,
                frame->width, frame->height, // picture width and height
                frame->linesize[0], //Y span/pitch
                frame->linesize[1], //UV span/pitch //frame->linesize[1]
                mSurfaceStride<<1, //bitmap span/pitch
                420);
#else
            struct yuv_pack out = {surfacePixels, (int32_t)mSurfaceStride * 4};
            struct yuv_planes in = {frame->data[0], frame->data[1], frame->data[2], frame->linesize[0]};
            i420_rgb_neon(&out, &in, frame->width, frame->height);
#endif // end of RENDER_RGB565
#else // __aarch64__
            I420ToABGR(frame->data[0], frame->linesize[0],
                       frame->data[1], frame->linesize[1],
                       frame->data[2], frame->linesize[2],
                       (uint8_t *)surfacePixels, mSurfaceStride * 4,
                       frame->width, frame->height);
#endif // end of __arm__
        }
        else {
            LOGW("surface memory is too small: surf_w %d, surf_h %d, surf_stride %d, frame_w %d, frame_h %d",
                 mSurfaceWidth, mSurfaceHeight, mSurfaceStride, frame->width, frame->height);
        }


        break;
    }
#ifdef __arm__ // only supported in armeabi
    case AV_PIX_FMT_NV12:
    {
        struct yuv_pack out = {surfacePixels, (int32_t)mSurfaceStride * 4};
        struct yuv_planes in = {frame->data[0], frame->data[1], frame->data[2], frame->linesize[0]};
        nv12_rgb_neon (&out, &in, frame->width, frame->height);
        break;
    }
    case AV_PIX_FMT_NV21:
    {
        struct yuv_pack out = {surfacePixels, (int32_t)mSurfaceStride * 4};
        struct yuv_planes in = {frame->data[0], frame->data[1], frame->data[2], frame->linesize[0]};
        nv21_rgb_neon (&out, &in, frame->width, frame->height);
        break;
    }
#endif
    default:
        LOGE("Video output format:%d does not support", mFrameFormat);
        return ERROR;
    }

    LOGD("before rendering frame");
    if(Surface_updateSurface(mNativeWindow) != OK) {
        LOGE("Failed to render picture");
        return ERROR;
    }
    LOGD("after rendering frame");

    int64_t end_scale = getNowMs();
    int64_t costTime = end_scale - begin_scale;
    if(mAveScaleTimeMs == 0) {
        mAveScaleTimeMs = costTime;
    }
    else {
        mAveScaleTimeMs = (mAveScaleTimeMs*4+costTime)/5;
    }
    LOGD("neon scale picture cost %lld[ms]", costTime);
    LOGV("mAveScaleTimeMs %lld[ms]", mAveScaleTimeMs);

    //For debug
    /*
    char path[1024] = {0};
    static int num=0;
    num++;
    sprintf(path, "/mnt/sdcard/frame_rgb_%d", num);
    LOGD("mSurfaceFrame->linesize[0]:%d, mOptiSurfaceHeight:%d", mSurfaceFrame->linesize[0], mOptiSurfaceHeight);
    saveFrameRGB(mSurfaceFrame->data[0], mSurfaceFrame->linesize[0], mOptiSurfaceHeight, path);
    */
    return OK;
#endif
}
Exemplo n.º 2
0
static void I420_RGBA (filter_t *filter, picture_t *src, picture_t *dst)
{
    struct yuv_pack out = { dst->p->p_pixels, dst->p->i_pitch };
    struct yuv_planes in = { src->Y_PIXELS, src->U_PIXELS, src->V_PIXELS, src->Y_PITCH };
    i420_rgb_neon (&out, &in, filter->fmt_in.video.i_width, filter->fmt_in.video.i_height);
}