I am trying to play live RTSP data on QNX Neutrino OS. I have created C code to do this and it works. I have connected my development kit and PC via ethernet. I can play RTSP video streamed from PC on my development kit but the first image is always distorted. The video is distorted for about 3-4 seconds on the screen.
My stream code in PC:
cvlc -vvv ~/Videos/bbb_sunflower_1080p_60fps_normal.mp4 --sout '#transcode{acodec=mp4a}:rtp{sdp=rtsp://:8554/stream}' :network-caching=1500
My C code in Development Kit(Plays video during 60 sec.):
#include <screen/screen.h>
#include <mm/renderer.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
#define WINGRP_NAME_MAX_LEN 128
// I/O devices
static const char *video_device_url = "screen:?winid=videosamplewindowgroup&wingrp=videosamplewindowgroup";
static const char *audio_device_url = "audio:default";
// Name of video context
static const char *video_context_name = "samplevideocontextname";
// Window group name
static const char *window_group_name = "videosamplewindowgroup";
// Window Name
const char *window_name = "appwindow";
strm_dict_t* calculate_rect(int width, int height) {
const int image_width = 640;
const int image_height = 480;
const float image_aspect = (float)image_width / (float)image_height;
const float aspect_tolerance = 0.1;
char buffer[16];
strm_dict_t *dict = strm_dict_new();
if (NULL == dict) {
return NULL;
}
//fullscreen is the default.
dict = strm_dict_set(dict, "video_dest_x", "0");
if (NULL == dict)
goto fail;
dict = strm_dict_set(dict, "video_dest_y", "0");
if (NULL == dict)
goto fail;
dict = strm_dict_set(dict, "video_dest_w", itoa(width, buffer, 10));
if (NULL == dict)
goto fail;
dict = strm_dict_set(dict, "video_dest_h", itoa(height, buffer, 10));
if (NULL == dict)
goto fail;
float screen_aspect = (float)width/(float)height;
dict = strm_dict_set(dict, "video_dest_x", itoa((width - image_width) / 2, buffer, 10));
if (NULL == dict)
goto fail;
width = height * image_aspect;
dict = strm_dict_set(dict, "video_dest_w", itoa(width, buffer, 10));
if (NULL == dict)
goto fail;
return dict;
fail:
strm_dict_destroy(dict);
return NULL;
}
int main(void) {
int rc;
int exit_application = 0;
printf("DBG-1n");
// Screen variables
screen_context_t screen_context = 0;
screen_window_t screen_window = 0;
int screen_size[2] = {0,0};
// Renderer variables
mmr_connection_t* mmr_connection = 0;
mmr_context_t* mmr_context = 0;
strm_dict_t* dict = NULL;
// I/O variables
int video_device_output_id = -1;
int audio_device_output_id = -1;
printf("DBG-2n");
/*
* Create the window used for video output.
*/
if (screen_create_context(&screen_context, SCREEN_APPLICATION_CONTEXT) != 0) {
return EXIT_FAILURE;
}
printf("DBG-3n");
if (screen_create_window(&screen_window, screen_context) != 0) {
screen_destroy_context(screen_context);
return EXIT_FAILURE;
}
printf("DBG-4n");
if (screen_create_window_group(screen_window, window_group_name) != 0) {
return EXIT_FAILURE;
}
printf("DBG-5n");
int format = SCREEN_FORMAT_RGBA8888;
if (screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_FORMAT, &format) != 0) {
return EXIT_FAILURE;
}
if(screen_set_window_property_cv(screen_window, SCREEN_PROPERTY_ID_STRING, 32, window_name)){
perror("Set Window ID Errorn");
return EXIT_FAILURE;
}
printf("DBG-6n");
int usage = SCREEN_USAGE_NATIVE;
if (screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_USAGE, &usage) != 0) {
return EXIT_FAILURE;
}
printf("DBG-7n");
if (screen_create_window_buffers(screen_window, 1) != 0) {
return EXIT_FAILURE;
}
printf("DBG-8n");
/*
* Configure mm-renderer.
*/
mmr_connection = mmr_connect(NULL);
if (mmr_connection == NULL) {
return EXIT_FAILURE;
}
printf("DBG-9n");
mmr_context = mmr_context_create(mmr_connection, video_context_name, 0, S_IRWXU|S_IRWXG|S_IRWXO);
if (mmr_context == NULL) {
return EXIT_FAILURE;
}
printf("DBG-11n");
/*
* Configure video and audio output.
*/
video_device_output_id = mmr_output_attach(mmr_context, video_device_url, "video");
if (video_device_output_id == -1) {
return EXIT_FAILURE;
}
printf("DBG-12n");
printf("DBG-13n");
// Get the render buffer
screen_buffer_t temp_buffer[1];
if (screen_get_window_property_pv( screen_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)temp_buffer) != 0) {
return EXIT_FAILURE;
}
printf("DBG-14n");
// Fill the buffer with a solid color (black)
int fill_attributes[3] = {SCREEN_BLIT_COLOR, 0x0, SCREEN_BLIT_END};
if (screen_fill(screen_context, temp_buffer[0], fill_attributes) != 0) {
return EXIT_FAILURE;
}
printf("DBG-15n");
// Make the window visible
if (screen_get_window_property_iv(screen_window, SCREEN_PROPERTY_SIZE, screen_size) != 0) {
return EXIT_FAILURE;
}
printf("DBG-16n");
int temp_rectangle[4] = {0, 0, screen_size[0], screen_size[1]};
if (screen_post_window(screen_window, temp_buffer[0], 1, temp_rectangle, 0) != 0) {
return EXIT_FAILURE;
}
printf("DBG-17n");
// Prevent the backlight from going off
int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
if (screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_IDLE_MODE, &idle_mode) != 0) {
return EXIT_FAILURE;
}
printf("DBG-18n");
// Build up the path where our bundled resource is.
char cwd[PATH_MAX];
char media_file[PATH_MAX];
getcwd(cwd,PATH_MAX);
rc = snprintf(media_file, PATH_MAX, "rtsp://10.42.0.1:8554/stream", cwd); // Play video RTSP
if ((rc == -1) || (rc >= PATH_MAX)) {
return EXIT_FAILURE;
}
printf("DBG-19n");
/*
* Start the playback.
*/
if (mmr_input_attach(mmr_context, media_file, "track") != 0) {
return EXIT_FAILURE;
}
printf("DBG-20n");
if (mmr_play(mmr_context) != 0) {
return EXIT_FAILURE;
}
printf("DBG-21n");
/* Do some work to make the aspect ratio correct.
*/
dict = calculate_rect(screen_size[0], screen_size[1]);
if (NULL == dict) {
return EXIT_FAILURE;
}
printf("DBG-22n");
if (mmr_output_parameters(mmr_context, video_device_output_id, dict) != 0) {
return EXIT_FAILURE;
}
dict = NULL;
sleep(60);
if (mmr_stop(mmr_context) != 0) {
return EXIT_FAILURE;
}
if (mmr_output_detach(mmr_context, audio_device_output_id) != 0) {
return EXIT_FAILURE;
}
if (mmr_output_detach(mmr_context, video_device_output_id) != 0) {
return EXIT_FAILURE;
}
if (mmr_context_destroy(mmr_context) != 0) {
return EXIT_FAILURE;
}
mmr_context = 0;
video_device_output_id = -1;
audio_device_output_id = -1;
mmr_disconnect(mmr_connection);
mmr_connection = 0;
if (screen_destroy_window(screen_window) != 0) {
return EXIT_FAILURE;
}
if (screen_destroy_context(screen_context) != 0) {
return EXIT_FAILURE;
}
screen_context = 0;
screen_window = 0;
return EXIT_SUCCESS;
}
First image after start play RTSP video:
I tried buffering the incoming RTSP data for 2 seconds and playing it, but it seems too complicated and I couldn’t do it. I couldn’t quite figure out if there was a problem with the stream.
How can I fix this issue?