SMP865X广告机之dcchd

来源:互联网 发布:西安爱知中学全名 编辑:程序博客网 时间:2024/05/08 12:40

作者 QQ: 35327864,msn: fgwf1@hotmail.com,mail: agooou@gmail.com

directfb
AMP
amp_test

main()
    global_init(): init osd layer and video layer.
        DirectFBInit (argc, argv);
        DirectFBCreate (&gdfb);
        gdfb->SetCooperativeLevel (gdfb, DFSCL_NORMAL);
        gdfb->GetScreen (gdfb, 0, &screen);
        gdfb->CreateInputEventBuffer (gdfb, DICAPS_KEYS, DFB_TRUE, &keybuffer);
        keybuffer->CreateFileDescriptor (keybuffer, &keyfd);
        init_osd_layer (false);
            gdfb->GetDisplayLayer (gdfb, DLID_PRIMARY, &layer);
            layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE);
            layer->SetBackgroundMode (layer, DLBM_DONTCARE);
            layer->EnableCursor (layer, 0);
            DFBDisplayLayerConfig dlcfg;
            dlcfg.flags = (DFBDisplayLayerConfigFlags) (DLCONF_BUFFERMODE|DLCONF_PIXELFORMAT);
            dlcfg.buffermode = osd2Buf ? DLBM_BACKVIDEO:DLBM_FRONTONLY;
            dlcfg.pixelformat = bpp == 8 ?DSPF_LUT8 : (bpp == 16 ? DSPF_ARGB4444 : DSPF_ARGB);
            layer->SetConfiguration (layer, &dlcfg);

        gdfb->GetDisplayLayer (gdfb, 2, &layer_mv);
        layer_mv->SetCooperativeLevel (layer_mv, DLSCL_EXCLUSIVE);
        layer->GetConfiguration (layer, &dlcfg); // find out size of the primay surface
        xres = dlcfg.width;
        yres = dlcfg.height;
       
        get_signal_resolution(signal);

        DFBFontDescription desc;
        desc.flags = DFDESC_HEIGHT;
        desc.height = yres/40;
        gdfb->CreateFont (gdfb, font_filename, &desc, &font);
        font->GetHeight (font, &fontheight);
        font->GetAscender (font, &fontascender);
        font->GetDescender (font, &fontdescender);

        global_init_osd_resources (osdBPP);
            init_osd_layer (bpp);
            layer->GetSurface (layer, &primary);
            primary->SetDrawingFlags (primary, DSDRAW_NOFX);
            layer->SetBackgroundColor (layer, 0xFF, 0xFF, 0xFF, 0x00);
            layer->SetBackgroundMode (layer, DLBM_COLOR);

        --enable_gui ()
            init_gui ()
                layer->CreateWindow (layer, &wdsc, &sts_window);
                layer->CreateWindow (layer, &wdsc, &msg_window);
                layer->CreateWindow (layer, &wdsc, &info_window);
                layer->CreateWindow (layer, &wdsc, &adj_window);
                info_window->LowerToBottom (info_window);
                msg_window->RaiseToTop (msg_window);

    init_hotplug ();
        check_mnt_point(INT_STOR);
        read_dev_properties(INT_STOR,&prop_i_stor);
        check_mnt_point(EXT_STOR);
        read_dev_properties(EXT_STOR,&prop_e_stor);
        open_fifo ()
            mkfifo ("/tmp/bdp.fifo", S_IRUSR|S_IWUSR); //why "/tmp/bdp.fifo", it is used by /sbin/usb-storage , which is in cs_rootfs_1.2.6/package/hotplug2/files/usb-storage:BDP_FIFO=/tmp/bdp.fifo
            hotplug_fd = open ("/tmp/bdp.fifo");
    gdfb->CreateImageProvider (gdfb, tinyGifName, &preLoadImg);
    gdfb->GetInterface (gdfb, "IAdvancedMediaProvider", NULL, (void*)(MAX_AMP_INSTANCES-1), (void*)&cfgamp);
    cfgamp->SetApplicationCallbacks (cfgamp, (void*)&processConfigPreview, (void*)&processConfigConfirm, CMD_INVALID_CALLBACK, CMD_INVALID_CALLBACK);
    cfgamp->GetDescription (cfgamp, &desc); //avoid of this call.
    if(pCrtVideoCfg) cfgamp->SetConfiguration (cfgamp, pCrtVideoCfg, NULL); //if not default video setting.
    print_video_settings (pCrtVideoCfg);
    if (pCrtAudioCfg) cfgamp->SetConfiguration (cfgamp, NULL, pCrtAudioCfg);
    print_audio_setting ();
    if (pCrtDRMCfg) cfgamp->SetConfiguration (cfgamp, NULL, NULL);
    print_drm_settings ();

    DFBScreenMixerConfig mixcfg;
    mixcfg.flags = (DFBScreenMixerConfigFlags) (DSMCONF_BACKGROUND|DSMCONF_LAYERS);
    mixcfg.background.a = 0;
    mixcfg.background.r = 0;
    mixcfg.background.g = 0;
    mixcfg.background.b = 0;
    DFB_DISPLAYLAYER_IDS_EMPTY (mixcfg.layers);
    DFB_DISPLAYLAYER_IDS_ADD (mixcfg.layers, EM86LAYER_OSD);
    if (useBackground) DFB_DISPLAYLAYER_IDS_ADD (mixcfg.layers, EM86LAYER_BKGND);
    screen->SetMixerConfiguration (screen, 0, &mixcfg);

    for (i=0; i < amps; i++)
    InitAMP (i);
        StartMediaPresentation(gdfb, i, &amp_table[i].ampfd, &amp_table[i].layerID, &amp_table[i].amp, &amp_table[i].img_size);
            dfb->GetInstance (dfb, "IAdvancedMediaPrivider", "EM8630", (void*)media->ampID, &dummy); //at this time, will power on hdmi.
            err = media->amp->GetEventBuffer(media->amp, &media->ampEvent);
            err = media->amp->OpenMedia (media->amp, media->url, &media->format, media->openParam);
                IAdvancedMediaProvider_EM8630_OpenMedia()
                    CreateLpbNavigator()
                        ThreadLauncher()
            media->ampEvent->WaitForEvent (media->ampEvent);
            DFBEvent event;
            media->ampEvent->GetEvent (media->ampEvent, &event);
            assert (media->ampEvent->HasEvent(media->ampEvent) != DFB_OK);
            ProcessMediaEvents (ampIndex);
                media->amp->UploadStatusChanges(media->amp, &media->status.generic, (DFBBollean)false);
            err = media->amp->StartPresentation(media->amp, (DFBBoolean)!media->noAutoPlay);
            media->ampEvent->WaitForEvent (media->ampEvent);
            DFBEvent event;
            media->ampEvent->GetEvent (media->ampEvent, &event);
            ProcessMediaEvents (ampIndex);
                media->amp->UploadStatusChanges(media->amp, &media->status.generic, (DFBBollean)false);
            err = media->ampEvent->CreateFileDescriptor (media->ampEvent, pEventFD); //this time we can create fd!!!
        // there is a special set for second video, do not use interlace.
        gdfb->GetDisplayLayer (gdfb, amp_table[i].layerID, &amp_table[i].layer);
        amp_table[i].layer->SetCooperativeLevel (amp_table[i].layer, DLSCL_EXCLUSIVE);
        amp_table[i].layer->SetScreenRectangle (amp_table[i].layer, amp_table[i].dst_area.x, amp_table[i].dst_area.y, amp_table[i].dst_area.w, amp_table[i].dst_area.h);
        screen->GetMixerConfiguration (screen, 0, &mixcfg);
        mixcfg.flags = DSMCONF_LAYERS;
        DFB_DISPLAYLAYER_IDS_ADD(mixcfg.layers, amp_table[i].layerID);
        if (layer_bg) DFB_DISPLAYLAYER_IDS_ADD(mixcfg.layers, EM86LAYER_BKGND);
        screen->SetMixerConfiguration (screen, 0, &mixcfg);
    set_active_amp (0, true, true);
        amp_table[ampIndex].layer->SetScreenRectangle (amp_table[ampIndex].layer, dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
        amp_table[ampIndex].layer->SetSourceRectangle (amp_table[ampIndex].layer, src_rect.x, src_rect.y, src_rect.w, src_rect.h);
        for (i=0; i<amps; i++)
        amp_table[i].layer->GetConfiguration(amp_table[i].layer, &lcfg);
        if (allow_screen_rect_change) amp_table[ampIndex].layer->SetScreenRectangle (amp_table[ampIndex].layer, dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
        if (allow_src_rect_change) amp_table[ampIndex].layer->SetSourceRectangle (amp_table[ampIndex].layer, src_rect.x, src_rect.y, src_rect.w, src_rect.h);
        if (amp_table[i].layerID == EM86LAYER_SECVIDEO) amp_table[i].layer->SetLevel (amp_table[i].layer, -2);
    //while (1) {
    FD_ZERO (&set);
    FD_SET (keyfd, &set);
    if (hotplug_fd != -1) FD_SET (hotplug_fd, &set);
    if (amp) FD_SET (ampfd, &set);
    select (FD_SETSIZE, &set, NULL, NULL, &timeout);
    if (FD_ISSET(keyfd,&set)) {
    } else if (FD_ISSET(ampfd, &set)) {
    } else if (FD_ISSET(hotplug_fd, &set)) {
    }
    //}
    if (cfgamp) cfgamp->Release (cfgamp);
    uninit_hotplug ();
        close_fifo ();
            close (hotplug_fd);
            unlink ("/tmp/bdp.fifo");
    global_uninit ();
        //for (i=0; i<amps; i++) {
        TerminateAMP (i, true);
            EndMediaPresentation (ampIndex, releaseAMP);
            disable_secosd_gui();
            disable_sv_layer ();
            screen->GetMixerConfiguration(screen, 0, &mixcfg);
            mixcfg.flags=(DFBScreenMixerConfigFlags)(DSMCONF_LAYERS);
            screen->SetMixerConfiguration(screen, 0, &mixcfg); //disable the layer output
            amp_table[ampIndex].layer->Release (amp_table[ampIndex].layer);
            //if EM86LAYER_SECVIDEO {
            screen->GetEncoderConfiguration (screen, 0, &enc_cfg);
            enc_cfg.flags=(DFBScreenEncoderConfigFlags) (DSECONF_DEINTERLACING_MODE|DSECONF_DELAYED_CONFIG);
            screen->SetEncoderConfiguration (screen, 0, &enc_cfg);
            //}
        FreePlaylist (i);
        //}
        disable_background_layer ();
        disable_sv_layer ();
        layer_mv->Release(layer_mv);
        global_uninit_osd_resources ();
        uninit_gui ();
        if(layer_sec)layer_sec->Release (layer_sec);
        if (font) font->Release (font);
        if (fontSmall) fontSmall->Release (fontSmall);
        if (screen) screen->Release (screen);
        if (keybuffer) keybuffer->Release (keybuffer);
        if (gdfb) gdfb->Release ();

注:
StartMediaPresentation详细过程:
    dfb->GetInstance (dfb, "IAdvancedMediaPrivider", "EM8630", (void*)media->ampID, &dummy); //at this time, will power on hdmi.
    err = media->amp->GetEventBuffer(media->amp, &media->ampEvent);
    err = media->amp->OpenMedia (media->amp, media->url, &media->format, media->openParam);
        IAdvancedMediaProvider_EM8630_OpenMedia()
            CreateLpbNavigator()
                ThreadLauncher()
    media->ampEvent->WaitForEvent (media->ampEvent);
    DFBEvent event;
    media->ampEvent->GetEvent (media->ampEvent, &event);
    assert (media->ampEvent->HasEvent(media->ampEvent) != DFB_OK);
    ProcessMediaEvents (ampIndex);
    err = media->amp->StartPresentation(media->amp, (DFBBoolean)!media->noAutoPlay);
    media->ampEvent->WaitForEvent (media->ampEvent);
    DFBEvent event;
    media->ampEvent->GetEvent (media->ampEvent, &event);
    ProcessMediaEvents (ampIndex);
    err = media->ampEvent->CreateFileDescriptor (media->ampEvent, pEventFD); //this time we can create fd!!!

关于DirectFB
DirectFB是dcchd的主要组成部分。SMP865X通过DirectFB抽象了底层的输入,OSD输出,Video输出等。
1,输入部分(Input Device)
    遥控器RC是被映射成一个输入设备,通过IDirectFBInputDevice接口使用。驱动将RC的keycode映射成DirectFB中的DIKS code(在directfb_keyboard.h中),并缓存到IDirectFBEventBuffer中,并可以通过一个file descriptor调用。之后,这个fd可以在线程中被select和read。
IDirectFBEventBuffer* keybuffer = NULL;
int keyfd;
DFBCHECK( gdfb->CreateInputEventBuffer (gdfb, DICAPS_KEYS, DFB_TRUE, &keybuffer));
DFBCHECK(keybuffer->CreateFileDescriptor (keybuffer, &keyfd))

2,显卡(Graphic Card)
    在通常情况下,smp863x有1个graphic层,2个video层,1个background层。顺序是固定的,从上到下分别为:graphic, video, background,但2个video层可以改变顺序。大部分画图操作已经被加速了,包含颜色转换,blit等。
FillRectangle(),Blit() ,TileBlit() ,StretchBlit() 已经被加速。

    A)Screen的配置(Screen Config)
        a)通过IDirectFBScreen接口进行设置。用Get/Test/SetXXXConfiguration的方法
        b)通过命令行或配置文件
        命令行下可用:--dfb:smp-gfx-only,配置文件有/etc/directfbrc,~/.directfbrc,/etc/directfbrc.execname或~/.directfbrc.execname,其中execname要替换成程序名。

    B)Layers配置
        a)Main Graphics layer ("OSD")
        b)Secondary Graphics layer ("SecOSD")
        c)Background layer ("BGND")
        d)Main Video layer ("MainVideo")
        e)Secondary Video layer ("2ndVideo")

    C)“GFX-only”模式
        之用directfb来进行加速,--dfb:smp-gfx-only,可以参考例子dfb_play_picture

    D)Image Provider接口

    E)Video Provider接口
        使用IDirectFBAdvancedMediaProvider
    F)Font Provide接口
        DrawString() 和DrawGlyph()加速了,用来进行写字。

3,AMP (Advanced Media Provider 接口)
    查看:AMP reference document.

原创粉丝点击