Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  cea708_integration.c   Sprache: C

 

/*****************************************************************************
 * cea708_integration.c: CEA-708 decoder integration tests
 *****************************************************************************
 * Copyright (C) 2025 VideoLAN and VLC Authors
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "../../libvlc/test.h"
#include "../../../lib/libvlc_internal.h"
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_modules.h>
#include <vlc_codec.h>
#include <vlc_subpicture.h>
#include <vlc_es.h>
#include <vlc_interface.h>

#include "../../../modules/codec/substext.h"

static libvlc_instance_t *libvlc;

struct cea708_test_owner {
    decoder_t dec;
    es_format_t fmt_in;
};

static decoder_t *create_cea708_decoder_test(const char *video_dimensions)
{
    vlc_object_t *obj = VLC_OBJECT(libvlc->p_libvlc_int);
    struct cea708_test_owner *owner = vlc_object_create(obj, sizeof(*owner));
    if (!owner)
        return NULL;
    decoder_t *dec = &owner->dec;

    es_format_t fmt;
    es_format_Init(&fmt, SPU_ES, VLC_CODEC_CEA708);
    fmt.subs.cc.i_channel = 1;
    fmt.subs.cc.i_reorder_depth = 4;

    decoder_Init(dec, &owner->fmt_in, &fmt);
    es_format_Clean(&fmt);

    dec->fmt_out.i_codec = VLC_CODEC_TEXT;

    /* Set up video format for aspect ratio testing */
    if (strcmp(video_dimensions, "4:3") == 0) {
        dec->fmt_out.video.i_visible_width = 640;
        dec->fmt_out.video.i_visible_height = 480;
        dec->fmt_out.video.i_sar_num = 1;
        dec->fmt_out.video.i_sar_den = 1;
    } else if (strcmp(video_dimensions, "16:9") == 0) {
        dec->fmt_out.video.i_visible_width = 1920;
        dec->fmt_out.video.i_visible_height = 1080;
        dec->fmt_out.video.i_sar_num = 1;
        dec->fmt_out.video.i_sar_den = 1;
    } else if (strcmp(video_dimensions, "anamorphic_4:3") == 0) {
        dec->fmt_out.video.i_visible_width = 720;
        dec->fmt_out.video.i_visible_height = 480;
        dec->fmt_out.video.i_sar_num = 8;
        dec->fmt_out.video.i_sar_den = 9;
    } else if (strcmp(video_dimensions, "anamorphic_16:9") == 0) {
        dec->fmt_out.video.i_visible_width = 720;
        dec->fmt_out.video.i_visible_height = 480;
        dec->fmt_out.video.i_sar_num = 32;
        dec->fmt_out.video.i_sar_den = 27;
    }

    /* Load CEA-708 decoder module */
    dec->p_module = module_need(dec, "spu decoder", "cc", true);

    return dec;
}

static void destroy_cea708_decoder_test(decoder_t *dec)
{
    struct cea708_test_owner *owner =
        container_of(dec, struct cea708_test_owner, dec);
    decoder_Clean(dec);
    es_format_Clean(&owner->fmt_in);
    vlc_object_delete(dec);
}

/* Test basic CEA-708 decoder loading */
static void test_cea708_decoder_loading(void)
{
    test_log("Testing CEA-708 decoder can be loaded\n");

    decoder_t *dec = create_cea708_decoder_test("16:9");
    assert(dec != NULL);
    assert(dec->p_module != NULL);

    test_log("CEA-708 decoder loaded successfully\n");

    destroy_cea708_decoder_test(dec);
}

/* Test CEA-708 decoder with different video formats */
static void test_cea708_decoder_with_different_formats(void)
{
    test_log("Testing CEA-708 decoder with different video formats\n");

    const char *formats[] = {"4:3", "16:9", "anamorphic_4:3", "anamorphic_16:9"};

    for (size_t i = 0; i < ARRAY_SIZE(formats); i++) {
        test_log("Testing with format: %s\n", formats[i]);

        decoder_t *dec = create_cea708_decoder_test(formats[i]);
        assert(dec != NULL);
        assert(dec->p_module != NULL);

        test_log("Format %s: decoder loaded successfully\n", formats[i]);

        destroy_cea708_decoder_test(dec);
    }
}

/* Test CEA-708 basic text output capability */
static void test_cea708_subtitle_text_output(void)
{
    test_log("Testing CEA-708 basic text output capability\n");

    decoder_t *dec = create_cea708_decoder_test("16:9");
    assert(dec != NULL);
    assert(dec->p_module != NULL);

    /* Simple CEA-708 test data */
    uint8_t test_data[] = {
        0x03, 0x80, 0x90,                    /* CEA-708 header */
        0x20, 0x48, 0x65, 0x6C, 0x6C, 0x6F,  /* "Hello" text */
        0x8F,                                /* End of window */
        0x00                                 /* End of data */
    };

    vlc_frame_t *frame = vlc_frame_Alloc(sizeof(test_data));
    assert(frame != NULL);
    memcpy(frame->p_buffer, test_data, sizeof(test_data));

    assert(dec->pf_decode != NULL);
    int result = dec->pf_decode(dec, frame);
    test_log("CEA-708 decode result: %d\n", result);
    assert(result == VLCDEC_SUCCESS);

    destroy_cea708_decoder_test(dec);
}

/* Test substext infrastructure with aspect ratio aware positioning
 * Per CEA-708-E Section 8.2: Infrastructure for aspect ratio aware rendering */

static void test_substext_infrastructure_with_aspect_ratio_positioning(void)
{
    test_log("Testing substext infrastructure with aspect ratio aware positioning\n");

    /* Test that both grid flags are now properly defined
     * Per CEA-708-E Section 8.2: Screen coordinate grid selection requires aspect ratio flags */

    assert(UPDT_REGION_USES_GRID_COORDINATES == (1 << 5));
    assert(UPDT_REGION_USES_16_9_GRID == (1 << 6));

    test_log("UPDT_REGION_USES_GRID_COORDINATES exists (0x%02x)\n",
             UPDT_REGION_USES_GRID_COORDINATES);
    test_log("UPDT_REGION_USES_16_9_GRID is available (0x%02x)\n",
             UPDT_REGION_USES_16_9_GRID);

    test_log("Available: UPDT_REGION_USES_16_9_GRID flag infrastructure\n");
    test_log("  This flag enables dynamic SAR selection per CEA-708-E Section 8.2\n");

    test_log("Aspect ratio aware positioning (CEA-708-E Section 8.2 compliance):\n");
    test_log("CEA-708 decoder now uses dynamic grid selection\n");
    test_log("4:3 content uses 160-column grid (CEA708_SCREEN_COLS_43)\n");
    test_log("16:9 content uses 210-column grid (CEA708_SCREEN_COLS_169)\n");
    test_log("UPDT_REGION_USES_16_9_GRID flag properly set based on DAR\n");
    test_log("Positioning accuracy fixed for all aspect ratios\n");
}

/* Test CEA-708 with positioning data (will expose positioning issues) */
static void test_cea708_real_positioning_data(void)
{
    test_log("Testing CEA-708 decoder with positioning data\n");

    /* CEA-708 positioning test data */
    const uint8_t cea708_window_positioning_data[] = {
        0x03, 0x80, 0x90,              /* CEA-708 header */
        0x98, 0x20, 0x50, 0x00,        /* Window definition with positioning */
        0x8A, 0x50, 0x50,              /* Set pen location (center) */
        0x20, 0x54, 0x65, 0x73, 0x74,  /* "Test" text */
        0x8F, 0x00                     /* End of window */
    };

    decoder_t *dec = create_cea708_decoder_test("16:9");
    assert(dec != NULL);
    assert(dec->p_module != NULL);

    vlc_frame_t *frame = vlc_frame_Alloc(sizeof(cea708_window_positioning_data));
    assert(frame != NULL);
    memcpy(frame->p_buffer, cea708_window_positioning_data, sizeof(cea708_window_positioning_data));
    frame->i_pts = VLC_TICK_0;
    frame->i_dts = VLC_TICK_0;

    assert(dec->pf_decode != NULL);
    int result = dec->pf_decode(dec, frame);
    test_log("CEA-708 positioning data decode result: %d\n", result);
    assert(result == VLCDEC_SUCCESS);

    test_log("Positioning data processed (complies with CEA-708-E Section 8.2)\n");
    destroy_cea708_decoder_test(dec);
}

/* Test end-to-end flow: Video format -> DAR -> Grid selection -> Flag setting -> Positioning
 * Per CEA-708-E Section 8.2: Complete integration validation */

static void test_end_to_end_aspect_ratio_flow(void)
{
    test_log("Testing end-to-end aspect ratio positioning flow\n");

    struct {
        const char *format_name;
        unsigned width, height, sar_num, sar_den;
        int expected_grid_cols;
        bool expected_16_9_flag;
        float test_anchor_h;
        float expected_position_ratio;
        const char *scenario;
    } integration_tests[] = {
        /* Standard broadcast formats */
        {"4:3_broadcast", 640, 480, 1, 1, 160, false, 80.0f, 0.5f, "4:3 broadcast center"},
        {"16:9_HDTV", 1920, 1080, 1, 1, 210, true, 105.0f, 0.5f, "16:9 HDTV center"},

        /* DVD anamorphic scenarios */
        {"DVD_4:3_anamorphic", 720, 480, 8, 9, 160, false, 80.0f, 0.5f, "DVD 4:3 anamorphic center"},
        {"DVD_16:9_anamorphic", 720, 480, 32, 27, 210, true, 105.0f, 0.5f, "DVD 16:9 anamorphic center"},

        /* Edge positioning tests */
        {"4:3_left_edge", 640, 480, 1, 1, 160, false, 0.0f, 0.0f, "4:3 left edge"},
        {"4:3_right_edge", 640, 480, 1, 1, 160, false, 159.0f, 0.99375f, "4:3 right edge"},
        {"16:9_left_edge", 1920, 1080, 1, 1, 210, true, 0.0f, 0.0f, "16:9 left edge"},
        {"16:9_right_edge", 1920, 1080, 1, 1, 210, true, 209.0f, 0.995238f, "16:9 right edge"},

        /* Cinema formats */
        {"DCI_2K_cinema", 2048, 858, 1, 1, 210, true, 105.0f, 0.5f, "DCI 2K cinema center"},
        {"ultra_wide", 3440, 1440, 1, 1, 210, true, 105.0f, 0.5f, "Ultra-wide monitor center"},
    };

    for (size_t i = 0; i < ARRAY_SIZE(integration_tests); i++) {
        test_log("\n--- Testing %s ---\n", integration_tests[i].scenario);

        /* Step 1: Create decoder with specific video format */
        vlc_object_t *obj = VLC_OBJECT(libvlc->p_libvlc_int);
        struct cea708_test_owner *owner = vlc_object_create(obj, sizeof(*owner));
        assert(owner != NULL);
        decoder_t *dec = &owner->dec;

        /* Step 2: Set up video format for DAR calculation */
        es_format_t fmt;
        es_format_Init(&fmt, SPU_ES, VLC_CODEC_CEA708);
        decoder_Init(dec, &owner->fmt_in, &fmt);
        es_format_Clean(&fmt);

        dec->fmt_out.i_codec = VLC_CODEC_TEXT;
        dec->fmt_out.video.i_visible_width = integration_tests[i].width;
        dec->fmt_out.video.i_visible_height = integration_tests[i].height;
        dec->fmt_out.video.i_sar_num = integration_tests[i].sar_num;
        dec->fmt_out.video.i_sar_den = integration_tests[i].sar_den;

        test_log("Video format: %ux%u SAR %u:%u\n",
                integration_tests[i].width, integration_tests[i].height,
                integration_tests[i].sar_num, integration_tests[i].sar_den);

        /* Step 3: Calculate expected DAR and grid selection */
        unsigned dar_num = integration_tests[i].width * integration_tests[i].sar_num;
        unsigned dar_den = integration_tests[i].height * integration_tests[i].sar_den;
        bool should_use_169_grid = (dar_num * 3 >= dar_den * 5);
        int expected_grid = should_use_169_grid ? 210 : 160;

        test_log("DAR calculation: %u:%u -> %s grid (%d columns)\n",
                dar_num, dar_den, should_use_169_grid ? "16:9" : "4:3", expected_grid);

        /* Step 4: Load decoder and verify it works */
        dec->p_module = module_need(dec, "spu decoder", "cc", true);
        assert(dec->p_module != NULL);

        /* Step 5: Create CEA-708 positioning test data with specific anchor */
        uint8_t cea708_positioning_data[] = {
            0x03, 0x80, 0x90,                                    /* CEA-708 header */
            0x98,                                                /* Define Window command */
            (uint8_t)(integration_tests[i].test_anchor_h),       /* anchor_h */
            0x25,                                                /* anchor_v (center) */
            0x00,                                                /* anchor_point = 0 (top-left) */
            0x8A, 0x50, 0x50,                                    /* Set pen location */
            0x20, 0x54, 0x65, 0x73, 0x74,                        /* "Test" text */
            0x8F, 0x00                                           /* End of window */
        };

        test_log("CEA-708 data: anchor_h=%.1f (expecting position ratio %.6f)\n",
                integration_tests[i].test_anchor_h, integration_tests[i].expected_position_ratio);

        /* Step 6: Decode the positioning command */
        vlc_frame_t *frame = vlc_frame_Alloc(sizeof(cea708_positioning_data));
        assert(frame != NULL);
        memcpy(frame->p_buffer, cea708_positioning_data, sizeof(cea708_positioning_data));
        frame->i_pts = VLC_TICK_0;
        frame->i_dts = VLC_TICK_0;

        assert(dec->pf_decode != NULL);
        int decode_result = dec->pf_decode(dec, frame);
        test_log("Decode result: %d (0=success)\n", decode_result);
        assert(decode_result == VLCDEC_SUCCESS);

        /* Step 7: Verify grid selection matches expectations */
        assert(expected_grid == integration_tests[i].expected_grid_cols);
        assert(should_use_169_grid == integration_tests[i].expected_16_9_flag);

        /* Step 8: Verify positioning calculation */
        float calculated_ratio = integration_tests[i].test_anchor_h / integration_tests[i].expected_grid_cols;
        test_log("Position verification: %.6f (expected %.6f)\n",
                calculated_ratio, integration_tests[i].expected_position_ratio);
        assert(fabs(calculated_ratio - integration_tests[i].expected_position_ratio) < 0.0001f);

        test_log("End-to-end flow verified for %s\n", integration_tests[i].scenario);

        /* Cleanup */
        decoder_Clean(dec);
        es_format_Clean(&owner->fmt_in);
        vlc_object_delete(dec);
    }

    test_log("\nAll end-to-end integration tests passed\n");
    test_log("Video format -> DAR -> Grid selection -> Flag setting -> Positioning flow validated\n");
}

int main(void)
{
    test_init();

    libvlc = libvlc_new(test_defaults_nargs, test_defaults_args);
    assert(libvlc != NULL);

    test_substext_infrastructure_with_aspect_ratio_positioning();
    test_cea708_decoder_loading();
    test_cea708_decoder_with_different_formats();
    test_cea708_subtitle_text_output();
    test_cea708_real_positioning_data();
    test_end_to_end_aspect_ratio_flow();

    libvlc_release(libvlc);

    return 0;
}

Messung
CHZG
89989694

¤ Dauer der Verarbeitung: 0.9 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104845
#Domains=499258