forked from Mirrors/freeswitch
[core,mod_av,unit-tests] Make transition to core packetizer
This commit is contained in:
parent
48e1812e29
commit
930341ba86
|
@ -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);
|
||||
}
|
||||
|
||||
context->nalus[i].len = p - context->nalus[i].start;
|
||||
context->nalu_current_index = 0;
|
||||
return consume_nalu(context, frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue