]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[core,mod_av,unit-tests] Make transition to core packetizer 2155/head
authorJakub Karolczyk <jakub.karolczyk@signalwire.com>
Mon, 10 Jul 2023 10:31:09 +0000 (10:31 +0000)
committerJakub Karolczyk <jakub.karolczyk@signalwire.com>
Mon, 10 Jul 2023 12:58:19 +0000 (12:58 +0000)
src/mod/applications/mod_av/avcodec.c
src/mod/applications/mod_av/avformat.c
src/switch_packetizer.c
tests/unit/switch_packetizer.c

index b4eaeadd2ef6b85ffe34ba7247ee53c21878103b..94cc9b36bfab5eb7a13de013b8713328e977e389 100644 (file)
@@ -399,6 +399,7 @@ typedef struct h264_codec_context_s {
        enum AVCodecID av_codec_id;
        uint16_t last_seq; // last received frame->seq
        int hw_encoder;
+       switch_packetizer_t *packetizer;
 } h264_codec_context_t;
 
 #ifndef AV_INPUT_BUFFER_PADDING_SIZE
@@ -1088,64 +1089,6 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw
        return SWITCH_STATUS_MORE_DATA;
 }
 
-static switch_status_t consume_h264_bitstream(h264_codec_context_t *context, switch_frame_t *frame)
-{
-       AVPacket *pkt = &context->encoder_avpacket;
-       our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
-       uint8_t nalu_hdr = *(uint8_t *)(nalu->start);
-       uint8_t nalu_type = nalu_hdr & 0x1f;
-       uint8_t nri = nalu_hdr & 0x60;
-       int left = nalu->len - (nalu->eat - nalu->start);
-       uint8_t *p = frame->data;
-       uint8_t start = nalu->start == nalu->eat ? 0x80 : 0;
-       int n = nalu->len / SLICE_SIZE;
-       int slice_size = nalu->len / (n + 1) + 1 + 2;
-
-       if (nalu->len <= SLICE_SIZE) {
-               memcpy(frame->data, nalu->start, nalu->len);
-               frame->datalen = nalu->len;
-               context->nalu_current_index++;
-
-               if (context->nalus[context->nalu_current_index].len) {
-                       frame->m = 0;
-                       return SWITCH_STATUS_MORE_DATA;
-               }
-
-               if (pkt->size > 0) av_packet_unref(pkt);
-
-               switch_clear_flag(frame, SFF_CNG);
-               frame->m = 1;
-
-               return SWITCH_STATUS_SUCCESS;
-       }
-
-       if (left <= (slice_size - 2)) {
-               p[0] = nri | 28; // FU-A
-               p[1] = 0x40 | nalu_type;
-               memcpy(p+2, nalu->eat, left);
-               nalu->eat += left;
-               frame->datalen = left + 2;
-               context->nalu_current_index++;
-
-               if (!context->nalus[context->nalu_current_index].len) {
-                       if (pkt->size > 0) av_packet_unref(pkt);
-                       frame->m = 1;
-                       return SWITCH_STATUS_SUCCESS;
-               }
-
-               return SWITCH_STATUS_MORE_DATA;
-       }
-
-       p[0] = nri | 28; // FU-A
-       p[1] = start | nalu_type;
-       if (start) nalu->eat++;
-       memcpy(p+2, nalu->eat, slice_size - 2);
-       nalu->eat += (slice_size - 2);
-       frame->datalen = slice_size;
-       frame->m = 0;
-       return SWITCH_STATUS_MORE_DATA;
-}
-
 static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame)
 {
        AVPacket *pkt = &context->encoder_avpacket;
@@ -1154,8 +1097,12 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_
        if (!nalu->len) {
                frame->datalen = 0;
                frame->m = 0;
-               if (pkt->size > 0) av_packet_unref(pkt);
+               if (pkt->size > 0) {
+                       av_packet_unref(pkt);
+               }
+
                context->nalu_current_index = 0;
+
                return SWITCH_STATUS_NOTFOUND;
        }
 
@@ -1167,7 +1114,9 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_
                return consume_h263p_bitstream(context, frame);
        }
 
-       return consume_h264_bitstream(context, frame);
+       switch_assert(0);
+
+       return SWITCH_STATUS_FALSE;
 }
 
 static void set_h264_private_data(h264_codec_context_t *context, avcodec_profile_t *profile)
@@ -1436,6 +1385,14 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
                }
        }
 
+       switch (context->av_codec_id) {
+       case AV_CODEC_ID_H264:
+               context->packetizer = switch_packetizer_create(SPT_H264_BITSTREAM, SLICE_SIZE);
+               break;
+       default:
+               break;
+       }
+
        switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0);
        codec->private_info = context;
 
@@ -1480,6 +1437,16 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
        }
 
        if (frame->flags & SFF_SAME_IMAGE) {
+               if (context->packetizer) {
+                       switch_status_t status = switch_packetizer_read(context->packetizer, frame);
+
+                       if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) {
+                               av_packet_unref(pkt);
+                       }
+
+                       return status;
+               }
+
                // read from nalu buffer
                return consume_nalu(context, frame);
        }
@@ -1511,7 +1478,9 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
                switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
        }
 
+GCC_DIAG_OFF(deprecated-declarations)
        av_init_packet(pkt);
+GCC_DIAG_ON(deprecated-declarations)
        pkt->data = NULL;      // packet data will be allocated by the encoder
        pkt->size = 0;
 
@@ -1596,8 +1565,7 @@ GCC_DIAG_ON(deprecated-declarations)
 // process:
 
        if (*got_output) {
-               const uint8_t *p = pkt->data;
-               int i = 0;
+               switch_status_t status = SWITCH_STATUS_SUCCESS;
 
                *got_output = 0;
 
@@ -1626,38 +1594,22 @@ GCC_DIAG_ON(deprecated-declarations)
                                                          "Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) nalu_type=0x%x %d\n",
                                                          context->pts, pkt->size, *((uint8_t *)pkt->data +4), *got_output);
                }
-               /* split into nalus */
-               memset(context->nalus, 0, sizeof(context->nalus));
-
-               while ((p = fs_avc_find_startcode(p, pkt->data+pkt->size)) < (pkt->data + pkt->size)) {
-                       if (!context->nalus[i].start) {
-                               while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
-                               context->nalus[i].start = p;
-                               context->nalus[i].eat = p;
-
-                               if ((*p & 0x1f) == 7) { // Got Keyframe
-                                       // prevent to generate key frame too frequently
-                                       context->last_keyframe_request = switch_time_now();
-                                       if (mod_av_globals.debug) {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
-                                       }
-                               }
-                       } else {
-                               context->nalus[i].len = p - context->nalus[i].start;
-                               while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
-                               i++;
-                               context->nalus[i].start = p;
-                               context->nalus[i].eat = p;
-                       }
-                       if (i >= MAX_NALUS - 2) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TOO MANY SLICES!\n");
-                               break;
+
+               status = switch_packetizer_feed(context->packetizer, pkt->data, pkt->size);
+               if (status != SWITCH_STATUS_SUCCESS) {
+                       if (pkt->size > 0) {
+                               av_packet_unref(pkt);
                        }
+
+                       return status;
                }
 
-               context->nalus[i].len = p - context->nalus[i].start;
-               context->nalu_current_index = 0;
-               return consume_nalu(context, frame);
+               status = switch_packetizer_read(context->packetizer, frame);
+               if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) {
+                       av_packet_unref(pkt);
+               }
+
+               return status;
        }
 
 error:
@@ -1708,7 +1660,9 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
                int decoded_len;
 
                if (size > 0) {
+GCC_DIAG_OFF(deprecated-declarations)
                        av_init_packet(&pkt);
+GCC_DIAG_ON(deprecated-declarations)
                        switch_buffer_zero_fill(context->nalu_buffer, AV_INPUT_BUFFER_PADDING_SIZE);
                        switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt.data);
                        pkt.size = size;
@@ -1825,6 +1779,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
                av_free(context->encoder_ctx);
        }
 
+       if (context->packetizer) {
+               switch_packetizer_close(&context->packetizer);
+       }
+
        if (context->encoder_avframe) {
                av_frame_free(&context->encoder_avframe);
        }
index d52e141b6b1b1725c196cd833697242691879156..d17f4eac390dead5123b9c6bc3efd385e2e3ce0d 100644 (file)
@@ -877,7 +877,9 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void *
 
                context->eh.in_callback = 1;
 
+GCC_DIAG_OFF(deprecated-declarations)
                av_init_packet(&pkt);
+GCC_DIAG_ON(deprecated-declarations)
 
                if (context->eh.video_st->frame) {
                        ret = av_frame_make_writable(context->eh.video_st->frame);
@@ -971,7 +973,9 @@ GCC_DIAG_ON(deprecated-declarations)
                int got_packet = 0;
                int ret = 0;
 
+GCC_DIAG_OFF(deprecated-declarations)
                av_init_packet(&pkt);
+GCC_DIAG_ON(deprecated-declarations)
 
 GCC_DIAG_OFF(deprecated-declarations)          
                ret = avcodec_encode_video2(context->eh.video_st->st->codec, &pkt, NULL, &got_packet);
@@ -1427,7 +1431,9 @@ GCC_DIAG_ON(deprecated-declarations)
 
 
 
+GCC_DIAG_OFF(deprecated-declarations)
                av_init_packet(&pkt);
+GCC_DIAG_ON(deprecated-declarations)
                pkt.data = NULL;
                pkt.size = 0;
 
@@ -1464,7 +1470,9 @@ GCC_DIAG_ON(deprecated-declarations)
                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %u %x %x %x %x %x %x\n", pkt.size, *p, *(p+1), *(p+2), *(p+3), *(p+4), *(p+5));
                                        }
 
+GCC_DIAG_OFF(deprecated-declarations)
                                        av_init_packet(new_pkt);
+GCC_DIAG_ON(deprecated-declarations)
                                        av_packet_ref(new_pkt, &pkt);
                                        status = switch_queue_push(context->video_pkt_queue, new_pkt);
                                        // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "size = %4u flag=%x pts=%" SWITCH_INT64_T_FMT " dts=%" SWITCH_INT64_T_FMT "\n", pkt.size, pkt.flags, pkt.pts, pkt.dts);
@@ -2102,8 +2110,10 @@ GCC_DIAG_ON(deprecated-declarations)
                int j = 0, ret = -1, audio_stream_count = 1;
                AVFrame *use_frame = NULL;
 
+GCC_DIAG_OFF(deprecated-declarations)
                av_init_packet(&pkt[0]);
                av_init_packet(&pkt[1]);
+GCC_DIAG_ON(deprecated-declarations)
 
                if (context->audio_st[1].active) {
                        switch_size_t len = 0;
index 626e85ba8ecfe76f7d3b51cc7377bc0eeb1d570b..c9cdcbf3e70d3fb2cfeead9ffc18f077dffc6a9d 100644 (file)
@@ -265,7 +265,7 @@ SWITCH_DECLARE(switch_status_t) switch_packetizer_feed(switch_packetizer_t *pack
                        context->nalus[i].eat = p;
                } else {
                        context->nalus[i].len = p - context->nalus[i].start;
-                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "#%d %x len=%u\n", i, *context->nalus[i].start, context->nalus[i].len);
+                       //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "#%d %x len=%u\n", i, *context->nalus[i].start, context->nalus[i].len);
                        while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
                        i++;
                        context->nalus[i].start = p;
@@ -307,8 +307,8 @@ SWITCH_DECLARE(switch_status_t) switch_packetizer_read(switch_packetizer_t *pack
        nri = nalu_hdr & 0x60;
 
        if (real_slice_size > slice_size) real_slice_size = slice_size;
-       if (frame->buflen < slice_size) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "frame buffer too small %u < %u\n", frame->buflen, slice_size);
+       if (frame->datalen < slice_size) {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "frame buffer too small %u < %u\n", frame->datalen, slice_size);
                return SWITCH_STATUS_FALSE;
        }
 
index 242ca6ae33c758e541244e5ee60a642228475782..006af5a74b5e95bfab7895da24863da8bc2113f5 100644 (file)
@@ -52,6 +52,7 @@ FST_CORE_BEGIN("conf")
 
                        frame.data = data;
                        frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+                       frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE;
                        switch_set_flag(&frame, SFF_ENCODED);
 
                        status = switch_packetizer_feed(packetizer, h264data, sizeof(h264data));
@@ -94,6 +95,7 @@ FST_CORE_BEGIN("conf")
 
                        frame.data = data;
                        frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+                       frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE;
                        switch_set_flag(&frame, SFF_ENCODED);
 
                        status = switch_packetizer_feed(packetizer, h264data, sizeof(h264data));
@@ -138,6 +140,7 @@ FST_CORE_BEGIN("conf")
 //                                                                                                                                     1 fps       3 bytes                 1pps        3 bytes
                        frame.data = data;
                        frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+                       frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE;
                        switch_set_flag(&frame, SFF_ENCODED);
 
                        status = switch_packetizer_feed_extradata(packetizer, extradata, sizeof(extradata));
@@ -210,6 +213,7 @@ FST_CORE_BEGIN("conf")
 
                        frame.data = data;
                        frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+                       frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE;
                        switch_set_flag(&frame, SFF_ENCODED);
 
                        status = switch_packetizer_feed(packetizer, h264data, sizeof(h264data));