Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] AWS kvssink shall not crash when providing pipeline with H265 encoding. #1213

Open
sbelbin opened this issue Dec 16, 2024 · 1 comment
Labels

Comments

@sbelbin
Copy link

sbelbin commented Dec 16, 2024

Logging

0:00:02.458971542 �[34m 1257�[00m    0x3024d21c0 �[37mDEBUG  �[00m �[00mGStreamerSwiftUIDemo GStreamerBackend.m:192:-[GStreamerBackend run_app_pipeline]:�[00m Creating pipeline
0:00:02.460718584 �[34m 1257�[00m    0x3024d21c0 �[31;01mERROR  �[00m �[00;01;37;41m        GST_PIPELINE gst/parse/grammar.y:1134:gst_parse_perform_link:�[00m could not link vtenc_h265-0 to kvssink0, vtenc_h265-0 can't handle caps video/x-h265, stream-format=(string)avc, alignment=(string)au, profile=(string)baseline
[INFO ] [16-12-2024 20:21:40:636.289 UTC] Logger config being used: /var/mobile/Containers/Data/Application/**********************/Documents/aws-kvs-log.cfg
[INFO ] [16-12-2024 20:21:40:636.611 UTC] User agent string: AWS-SDK-KVS-CPP-CLIENT/3.4.2
[INFO ] [16-12-2024 20:21:40:646.267 UTC] createKinesisVideoClient(): Creating Kinesis Video Client
[TRACE] [16-12-2024 20:21:40:646.439 UTC] normalizeExponentialBackoffConfig(): Thread Id [6170980352]. Exponential backoff retry strategy config - maxRetryCount: [0], maxRetryWaitTime: [100000000], retryFactorTime: [1000000], minTimeToResetRetryState: [900000000], jitterType: [1], jitterFactor: [0], 
[TRACE] [16-12-2024 20:21:40:646.491 UTC] resetExponentialBackoffRetryState(): Thread Id [6170980352]. Resetting Exponential Backoff State. Last retry system time [0], retry count so far [0], Current system time [17343805006464890]
[TRACE] [16-12-2024 20:21:40:646.559 UTC] exponentialBackoffRetryStrategyCreate(): Created exponential backoff retry strategy state with provided retry configuration.
[INFO ] [16-12-2024 20:21:40:646.621 UTC] heapInitialize(): Initializing native heap with limit size 134217728, spill ratio 0% and flags 0x00000001
[INFO ] [16-12-2024 20:21:40:646.661 UTC] heapInitialize(): Creating AIV heap.
[INFO ] [16-12-2024 20:21:40:646.739 UTC] heapInitialize(): Heap is initialized OK
[TRACE] [16-12-2024 20:21:40:646.892 UTC] stepStateMachine(): [CLIENT] State Machine - Current state: 0x0000000000000001, Next state: 0x0000000000000002, Current local state retry count [0], Max local state retry count [5], State transition wait time [0] ms
[DEBUG] [16-12-2024 20:21:40:646.943 UTC] getSecurityTokenHandler invoked
[DEBUG] [16-12-2024 20:21:40:646.986 UTC] Refreshing credentials. Force refreshing: 0 Now time is: 1734380500646978 Expiration: 0
[TRACE] [16-12-2024 20:21:40:647.052 UTC] stepStateMachine(): [CLIENT] State Machine - Current state: 0x0000000000000002, Next state: 0x0000000000000010, Current local state retry count [0], Max local state retry count [5], State transition wait time [0] ms
[INFO ] [16-12-2024 20:21:40:647.129 UTC] createDeviceResultEvent(): Create device result event.
[TRACE] [16-12-2024 20:21:40:647.195 UTC] stepStateMachine(): [CLIENT] State Machine - Current state: 0x0000000000000010, Next state: 0x0000000000000040, Current local state retry count [0], Max local state retry count [0], State transition wait time [0] ms
[DEBUG] [16-12-2024 20:21:40:647.235 UTC] clientReadyHandler invoked
[TRACE] [16-12-2024 20:21:40:647.269 UTC] createKinesisVideoClientSync(): Awaiting for the Kinesis Video Client to become ready...
[TRACE] [16-12-2024 20:21:40:647.300 UTC] createKinesisVideoClientSync(): Kinesis Video Client is Ready.

Describe the bug
When running a sample app running on an iPad device where the pipeline passed to GStreamer is the following:

"avfvideosrc ! video/x-raw, width=1280, height=720, framerate=30/1 ! videoconvert ! vtenc_h265 ! video/x-h265, stream-format=avc, alignment=au, profile=baseline ! kvssink stream-name=neuroservo-sbelbin-test storage-size=128 aws-region=%s access-key=%s secret-key=%s log-config=%s"

This results in the kvssink GStreamer plugin causing an app crash with a BAD_ACCESS due to a null reference access when transitiioning to a PLAY state.

Expected behavior
Although there is an error the pipeline still this shall not result in a BAD_ACCESS exception from the kvssink plugin later on. Instead it shall gracefully error and ideally report that the operation cannot be performed due to unsupported encoding in the pipeline.

0:00:02.460718584 �[34m 1257�[00m    0x3024d21c0 �[31;01mERROR  �[00m �[00;01;37;41m        GST_PIPELINE gst/parse/grammar.y:1134:gst_parse_perform_link:�[00m could not link vtenc_h265-0 to kvssink0, vtenc_h265-0 can't handle caps video/x-h265, stream-format=(string)avc, alignment=(string)au, profile=(string)baseline

SDK version number
Using the source code from master branch.

Open source building

  • Built using iOS SDK
  • Everything is built as a static library, since deployment of GStreamer for iOS expects plugins as static libraries.

Screenshots
N/A

Platform (please complete the following information):

  • OS: iOS
  • Processor: ARM64
  • Version iOS 18.2

Additional context

The crash is at this line of code is in the init_track_data function gstkvssink.c when the return of calling the gst_pad_get_allowed_caps returns a NULL value into the caps variable.

Since the code lacks to verify if that variable is NULL, then the subsequent will eventually result in a BAD_ACCESS failure. The code needs to check for NULL and take the appropriate actions.

    for (walk = kvssink->collect->data; walk != NULL; walk = g_slist_next (walk)) {
        GstKvsSinkTrackData *kvs_sink_track_data = (GstKvsSinkTrackData *) walk->data;

        if (kvs_sink_track_data->track_type == MKV_TRACK_INFO_TYPE_VIDEO) {

            if (kvssink->data->media_type == AUDIO_VIDEO) {
                kvs_sink_track_data->track_id = KVS_SINK_DEFAULT_TRACKID;
            }

            GstCollectData *collect_data = (GstCollectData *) walk->data;

            // extract media type from GstCaps to check whether it's h264 or h265
            caps = gst_pad_get_allowed_caps(collect_data->pad);
            media_type = gst_structure_get_name(gst_caps_get_structure(caps, 0));
            if (strncmp(media_type, GSTREAMER_MEDIA_TYPE_H264, MAX_GSTREAMER_MEDIA_TYPE_LEN) == 0) {
                // default codec id is for h264 video.
                video_content_type = g_strdup(MKV_H264_CONTENT_TYPE);
            } else if (strncmp(media_type, GSTREAMER_MEDIA_TYPE_H265, MAX_GSTREAMER_MEDIA_TYPE_LEN) == 0) {
                g_free(kvssink->codec_id);
                kvssink->codec_id = g_strdup(DEFAULT_CODEC_ID_H265);
                video_content_type = g_strdup(MKV_H265_CONTENT_TYPE);
            } else {
                // no-op, should result in a caps negotiation error before getting here.
                LOG_AND_THROW("Error, media type " << media_type << "not accepted by kvssink" << " for " << kvssink->stream_name);
            }
            gst_caps_unref(caps);

        } else if (kvs_sink_track_data->track_type == MKV_TRACK_INFO_TYPE_AUDIO) {
@sbelbin sbelbin added the bug label Dec 16, 2024
@stefankiesz
Copy link
Contributor

Hi Steven, thank you very much for all your work on this kvssink-iOS integration and details shared along the way.

I confirmed per GStreamer documentation, gst_pad_get_allowed_caps "returns NULL when pad has no peer." I'll put out a fix for this shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants