Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions DemuxDataTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct MediaCodecInfo
* Uniform initialization is preferred for C++ types as it's type-safe, clearer in intent,
* and works correctly with all C++ types including those with constructors.
*/
MediaCodecInfo() : mCodecFormat(GST_FORMAT_INVALID), mIsEncrypted(false), mNaluLengthPrefixed(false), mCodecData(), mInfo{0}
MediaCodecInfo() : mCodecFormat(GST_FORMAT_INVALID), mCodecData(), mIsEncrypted(false), mNaluLengthPrefixed(false), mInfo{}
{
}

Expand All @@ -133,7 +133,7 @@ struct MediaCodecInfo
* Uniform initialization is preferred for C++ types as it's type-safe, clearer in intent,
* and works correctly with all C++ types including those with constructors.
*/
MediaCodecInfo(GstStreamOutputFormat format) : mCodecFormat(format), mIsEncrypted(false), mNaluLengthPrefixed(false), mCodecData(), mInfo{0}
MediaCodecInfo(GstStreamOutputFormat format) : mCodecFormat(format), mCodecData(), mIsEncrypted(false), mNaluLengthPrefixed(false), mInfo{}
{
}

Expand Down
110 changes: 110 additions & 0 deletions PLAYER-SIMULATOR-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Player Interface CLI Test Player

## Goal and constraints

Build a lightweight Linux console player under `test/pi-cli/` that exercises
Player Interface during real clear HLS and DASH playback. The simulator must
not change Player Interface production or vendor code.

- Use FFmpeg for manifest loading, HTTP(S) fetching, and demuxing.
- Keep media payloads in bounded heap-backed queues; never write manifests or
media segments to local files.
- Pass compressed audio/video samples through Player Interface's
`NeedData`/`EnoughData` and `SendHelper()` APIs.
- Leave decoding, A/V synchronization, and rendering to Player Interface.
- Do not create a second media pipeline or call media-pipeline APIs directly
from pi-cli.
- Ignore DRM and subtitles initially. Start with H.264 video and AAC audio.
- Keep CLI controls and diagnostics independent of other player tools; use
Player Interface's sample-injection API as the playback boundary.

## Data flow

```text
HLS/DASH URL
|
v
FFmpeg libavformat
manifest and segment HTTP(S) fetch
adaptive demux to compressed audio/video packets
|
v
bounded heap queues <---- Player Interface NeedData / EnoughData
|
v
Player Interface SendHelper()
|
v
Player Interface decode, synchronization, and platform output
```

FFmpeg is an ingest/demux layer only; it does not decode or render. The
simulator does not write to a disk cache. H.264 Annex-B packets are converted
to four-byte length-prefixed access units with AVC codec configuration for
Player Interface's H.264 caps. AAC uses the demuxer's ADTS framing for
transport streams and raw AAC plus AudioSpecificConfig for containerized
streams.

## Implementation phases and gates

### Phase 1 — Standalone build

- Keep the CLI entry point and console parser under `test/pi-cli/`.
- Build against the installed Player Interface package and GLib.
- Add FFmpeg `libavformat`, `libavcodec`, and `libavutil` development modules.
- Add libxml2 for in-memory DASH manifest filtering.
- Do not add GStreamer factory checks or build a media pipeline in pi-cli.

**Gate:** configure and build on Ubuntu without changing the root Player
Interface build.

### Phase 2 — FFmpeg source and sample bridge

- Open HLS/DASH manifests using FFmpeg's network protocols and demuxers.
- Filter DASH manifests in memory to the lowest-bandwidth video representation
and one non-commentary audio adaptation set before opening FFmpeg's DASH
demuxer; that demuxer opens every advertised representation's initialization
segment during manifest open.
- Select playback audio/video tracks before stream probing and ignore subtitle
streams.
- Select supported H.264/AAC tracks; ignore subtitle streams.
- Keep packet data in bounded heap-backed per-track queues.
- Register Player Interface `NeedData` and `EnoughData` callbacks before
configuring streams.
- Configure finite Player Interface appsrc queue limits so `EnoughData`
backpressure is active rather than leaving appsrc queues unlimited.
- Configure the Player Interface tracks from FFmpeg codec metadata, then feed
samples with timestamps and discontinuity state through `SendHelper()`.
- Signal per-track end-of-stream after queued packets drain.
- Stop and interrupt FFmpeg network reads cleanly during teardown.
- Bound network reads with a timeout and log each startup/probe stage,
including DASH manifest fetch and filtering.
- Log a bounded sample of packet timestamps, `NeedData`/`EnoughData` transitions,
sample submission results, and playback position to diagnose stalled output.

**Gate:** logs show packet injection and Player Interface callbacks for one
clear HLS stream and one clear DASH stream. Confirm no media files are created.

### Phase 3 — Console controls

- Keep `play`, `pause`, `seek`, `trick`, `stop`, `status`, and `quit` in the
console frontend.
- Coordinate seeks across FFmpeg demux and Player Interface flush operations.
- Preserve `NeedData`/`EnoughData` backpressure during pause, seek, and resume.
- Report FFmpeg and Player Interface failures explicitly.

**Gate:** on Ubuntu, verify pause/resume, seek, supported trick rates, EOS,
errors, and clean shutdown. Platform-specific trick playback is not assumed
until tested.

### Phase 4 — Playback validation and coverage

- Validate packet framing, timestamps, codec configuration, and A/V output on
representative HLS MPEG-TS, HLS fMP4, and DASH fMP4 streams.
- Add support only for clear codecs/framing confirmed against Player Interface
caps; reject unsupported codecs clearly.
- Use startup milestones to distinguish manifest probing, first packet
arrival, Player Interface setup, first sample processing, and first frame.

**Gate:** build and playback checks on Ubuntu. Windows-only inspection cannot
confirm Linux sink behavior or end-to-end playback.
75 changes: 35 additions & 40 deletions test/pi-cli/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,57 +1,52 @@
cmake_minimum_required(VERSION 3.10)

# Project name
project(pi-cli VERSION 1.0 LANGUAGES CXX)
project(pi-player-simulator LANGUAGES CXX)

set(PI_ROOT "../..")

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

include_directories(${PI_ROOT})

# Find GStreamer packages
find_package(PkgConfig REQUIRED)
pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
pkg_check_modules(GSTREAMERBASE REQUIRED gstreamer-app-1.0)

include_directories(${GSTREAMER_INCLUDE_DIRS})
include_directories(${GSTREAMERBASE_INCLUDE_DIRS})

# Add the executable (now includes commandProcessing.cpp)
add_executable(pi-cli
main.cpp
commandProcessing.cpp
pkg_check_modules(PLAYERGSTINTERFACE REQUIRED IMPORTED_TARGET libplayergstinterface)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0 gio-2.0)
pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET
libavformat
libavcodec
libavutil
)
pkg_check_modules(LIBXML2 REQUIRED IMPORTED_TARGET libxml-2.0)

add_executable(pi-player-simulator
src/main.cpp
src/backend/AbrController.cpp
src/backend/SegmentResourceProxy.cpp
src/backend/StreamDemuxSource.cpp
src/backend/MediaTrackCatalog.cpp
src/backend/PlayerBackend.cpp
src/console/ConsolePlayer.cpp
)

# Use pkg-config to locate the readline library
pkg_check_modules(READLINE REQUIRED readline)
target_compile_features(pi-player-simulator PRIVATE cxx_std_17)
target_include_directories(pi-player-simulator PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../..
)
target_link_libraries(pi-player-simulator PRIVATE
PkgConfig::PLAYERGSTINTERFACE
PkgConfig::GLIB
PkgConfig::FFMPEG
PkgConfig::LIBXML2
)
Comment on lines +30 to +35

if (READLINE_FOUND)
include_directories(${READLINE_INCLUDE_DIRS})
link_directories(${READLINE_LIBRARY_DIRS})
target_link_libraries(pi-cli ${READLINE_LIBRARIES})
else()
message(FATAL_ERROR "Readline library not found. Please install it.")
if(NOT UNIX)
message(FATAL_ERROR "pi-player-simulator console input requires a Unix-like platform")
endif()

# Add OpenSSL requirement so we can link crypto/ssl symbols
find_package(OpenSSL REQUIRED)

target_link_libraries(pi-cli playergstinterface OpenSSL::Crypto OpenSSL::SSL)
if(BUILD_WITH_COVERAGE)
target_compile_options(pi-cli PRIVATE --coverage)
target_compile_options(pi-player-simulator PRIVATE --coverage)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.13")
target_link_options(pi-cli PRIVATE --coverage)
target_link_options(pi-player-simulator PRIVATE --coverage)
else()
# Fallback for older CMake versions that do not support target_link_options
set_target_properties(pi-cli PROPERTIES LINK_FLAGS "--coverage")
set_target_properties(pi-player-simulator PROPERTIES LINK_FLAGS "--coverage")
endif()
message(STATUS "pi-cli: Building with coverage instrumentation")
endif()

# Additional warnings and flags for development
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(pi-cli PRIVATE -Wall -Wextra -pedantic)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(pi-player-simulator PRIVATE -Wall -Wextra -Wpedantic)
endif()
64 changes: 0 additions & 64 deletions test/pi-cli/Dockerfile

This file was deleted.

Loading
Loading