From c0f3b52b94a4397263fc38c1bbc2fa06229c5cb7 Mon Sep 17 00:00:00 2001 From: fduncanh Date: Sat, 16 Apr 2022 20:12:30 -0400 Subject: [PATCH] set h264 "type" to nal_count --- lib/raop_rtp_mirror.c | 17 ++++----- lib/stream.h | 5 +-- renderers/video_renderer.h | 2 +- renderers/video_renderer_gstreamer.c | 8 ++-- uxplay.cpp | 57 ++++++++++++---------------- 5 files changed, 38 insertions(+), 51 deletions(-) diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index de2557e..0b6168f 100644 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -400,26 +400,23 @@ raop_rtp_mirror_thread(void *arg) if (nalu_size != payload_size) valid_data = false; if(!valid_data) { logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "nalu marked as invalid"); + payload_out[0] = 1; /* mark video data as invalid h264 (failed decryption) */ } #ifdef DUMP_H264 fwrite(payload_decrypted, payload_size, 1, file); #endif + payload_decrypted = NULL; h264_decode_struct h264_data; h264_data.pts = ntp_timestamp; - h264_data.frame_type = payload_decrypted[4] & 0x1f; + h264_data.nal_count = nalus_count; /*frame_type is set to number of nal units in packet */ + h264_data.data_len = payload_size; + h264_data.data = payload_out; if (prepend_sps_pps) { - h264_data.data = payload_out; - h264_data.data_len = payload_size + sps_pps_len; + h264_data.data_len += sps_pps_len; + h264_data.nal_count += 2; if (ntp_timestamp_raw != ntp_timestamp_nal) { logger_log(raop_rtp_mirror->logger, LOGGER_WARNING, "raop_rtp_mirror: prepended sps_pps timestamp does not match that of video payload"); } - } else { - h264_data.data_len = payload_size; - h264_data.data = payload_decrypted; - } - - if (!valid_data) { - h264_data.data[0] = 1; /* mark video data as invalid h264 (failed decryption) */ } raop_rtp_mirror->callbacks.video_process(raop_rtp_mirror->callbacks.cls, raop_rtp_mirror->ntp, &h264_data); free(payload_out); diff --git a/lib/stream.h b/lib/stream.h index a801f4c..93aed8d 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -18,12 +18,9 @@ #include typedef struct { - int n_gop_index; - int frame_type; - int n_frame_poc; + int nal_count; unsigned char *data; int data_len; - unsigned int n_time_stamp; uint64_t pts; } h264_decode_struct; diff --git a/renderers/video_renderer.h b/renderers/video_renderer.h index 5e9fb95..dd0760c 100644 --- a/renderers/video_renderer.h +++ b/renderers/video_renderer.h @@ -49,7 +49,7 @@ void video_renderer_init (logger_t *logger, const char *server_name, videoflip_t const char *decoder, const char *converter, const char *videosink); void video_renderer_start (); void video_renderer_stop (); -void video_renderer_render_buffer (raop_ntp_t *ntp, unsigned char* data, int data_len, uint64_t pts, int type); +void video_renderer_render_buffer (raop_ntp_t *ntp, unsigned char* data, int data_len, uint64_t pts, int nal_count); void video_renderer_flush (); unsigned int video_renderer_listen(void *loop); void video_renderer_destroy (); diff --git a/renderers/video_renderer_gstreamer.c b/renderers/video_renderer_gstreamer.c index 4e837ac..7f4d34f 100644 --- a/renderers/video_renderer_gstreamer.c +++ b/renderers/video_renderer_gstreamer.c @@ -182,10 +182,12 @@ void video_renderer_start() { first_packet = true; } -void video_renderer_render_buffer(raop_ntp_t *ntp, unsigned char* data, int data_len, uint64_t pts, int type) { +void video_renderer_render_buffer(raop_ntp_t *ntp, unsigned char* data, int data_len, uint64_t pts, int nal_count) { GstBuffer *buffer; assert(data_len != 0); - /* first four bytes of valid video data are 0x0, 0x0, 0x0, 0x1 */ + /* first four bytes of valid h264 video data are 0x0, 0x0, 0x0, 0x1 */ + /* nal_count is the number of NAL units in the data: SPS, PPS, SEI NALs may precede a VCL NAL */ + /* each NAL is byte-aligned, starts with 0x00 0x00 0x00 0x01 */ /* first byte of invalid data (decryption failed) is 0x1 */ if (data[0]) { logger_log(logger, LOGGER_ERR, "*** ERROR decryption of video packet failed "); @@ -196,7 +198,7 @@ void video_renderer_render_buffer(raop_ntp_t *ntp, unsigned char* data, int data } buffer = gst_buffer_new_and_alloc(data_len); assert(buffer != NULL); - GST_BUFFER_DTS(buffer) = (GstClockTime)pts; + GST_BUFFER_DTS(buffer) = (GstClockTime) pts; gst_buffer_fill(buffer, 0, data, data_len); gst_app_src_push_buffer (GST_APP_SRC(renderer->appsrc), buffer); #ifdef X_DISPLAY_FIX diff --git a/uxplay.cpp b/uxplay.cpp index d2a2cde..024f128 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -132,49 +132,40 @@ void dump_audio_to_file(unsigned char *data, int datalen, unsigned char type) { } } -void dump_video_to_file(unsigned char *data, int datalen, int type) { - - /* type 5 NAL's are preceded by a PPS and SPS */ - if (type == 5 && video_dumpfile && video_dump_limit) { +void dump_video_to_file(unsigned char *data, int datalen) { + /* SPS NAL has (data[4] & 0x1f) = 0x07 */ + if ((data[4] & 0x1f) == 0x07 && video_dumpfile && video_dump_limit) { + fwrite(mark, 1, sizeof(mark), video_dumpfile); + fclose(video_dumpfile); + video_dumpfile = NULL; + video_dump_count = 0; } - if (video_dump_limit == 0) { - if (!video_dumpfile) { - std::string fn = video_dumpfile_name; - fn.append(".h264"); - video_dumpfile = fopen (fn.c_str(),"w"); - if (video_dumpfile == NULL) { - LOGE("could not open file %s for dumping h264 frames",fn.c_str()); - } - } - } else if (type == 5) { - char suffix[20]; + if (!video_dumpfile) { std::string fn = video_dumpfile_name; - video_dumpfile_count++; - snprintf(suffix, sizeof(suffix), ".%d.h264", video_dumpfile_count); - fn.append(suffix); - if (video_dumpfile) { - fwrite(mark, 1, sizeof(mark), video_dumpfile); - fclose(video_dumpfile); - } + if (video_dump_limit) { + char suffix[20]; + video_dumpfile_count++; + snprintf(suffix, sizeof(suffix), ".%d", video_dumpfile_count); + fn.append(suffix); + } + fn.append(".h264"); video_dumpfile = fopen (fn.c_str(),"w"); if (video_dumpfile == NULL) { LOGE("could not open file %s for dumping h264 frames",fn.c_str()); - } + } } - + if (video_dumpfile) { - fwrite(data, 1, datalen, video_dumpfile); - if (video_dump_limit) { + if (video_dump_limit == 0) { + fwrite(data, 1, datalen, video_dumpfile); + } else if (video_dump_count < video_dump_limit) { video_dump_count++; - if (video_dump_count == video_dump_limit) { - fwrite(mark, 1, sizeof(mark), video_dumpfile); - fclose(video_dumpfile); - video_dumpfile = NULL; - } + fwrite(data, 1, datalen, video_dumpfile); } } } + static gboolean connection_callback (gpointer loop){ if (!connections_stopped) { counter = 0; @@ -805,10 +796,10 @@ extern "C" void audio_process (void *cls, raop_ntp_t *ntp, aac_decode_struct *da extern "C" void video_process (void *cls, raop_ntp_t *ntp, h264_decode_struct *data) { if (dump_video) { - dump_video_to_file(data->data, data->data_len, data->frame_type); + dump_video_to_file(data->data, data->data_len); } if (use_video) { - video_renderer_render_buffer(ntp, data->data, data->data_len, data->pts, data->frame_type); + video_renderer_render_buffer(ntp, data->data, data->data_len, data->pts, data->nal_count); } }