forked from Mirrors/freeswitch
[mod_av] Migrate to FFmpeg 5.1
This commit is contained in:
parent
2f81317ac1
commit
667783831b
|
@ -26,6 +26,7 @@
|
|||
* Seven Du <dujinfang@gmail.com>
|
||||
* Anthony Minessale <anthm@freeswitch.org>
|
||||
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
||||
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||
*
|
||||
* mod_avcodec -- Codec with libav.org and ffmpeg
|
||||
*
|
||||
|
@ -373,8 +374,13 @@ typedef struct our_h264_nalu_s {
|
|||
|
||||
typedef struct h264_codec_context_s {
|
||||
switch_buffer_t *nalu_buffer;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
AVCodec *decoder;
|
||||
AVCodec *encoder;
|
||||
#else
|
||||
const AVCodec *decoder;
|
||||
const AVCodec *encoder;
|
||||
#endif
|
||||
AVCodecContext *decoder_ctx;
|
||||
int got_pps; /* if pps packet received */
|
||||
int64_t pts;
|
||||
|
@ -393,7 +399,7 @@ typedef struct h264_codec_context_s {
|
|||
switch_codec_settings_t codec_settings;
|
||||
AVCodecContext *encoder_ctx;
|
||||
AVFrame *encoder_avframe;
|
||||
AVPacket encoder_avpacket;
|
||||
AVPacket *encoder_avpacket;
|
||||
AVFrame *decoder_avframe;
|
||||
our_h264_nalu_t nalus[MAX_NALUS];
|
||||
enum AVCodecID av_codec_id;
|
||||
|
@ -826,7 +832,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p
|
|||
const uint8_t *p = buf;
|
||||
const uint8_t *buf_base = buf;
|
||||
uint32_t code = (ntohl(*(uint32_t *)buf) & 0xFFFFFC00) >> 10;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
int mb_info_size = 0;
|
||||
#else
|
||||
switch_size_t mb_info_size = 0;
|
||||
#endif
|
||||
int mb_info_pos = 0, mb_info_count = 0;
|
||||
const uint8_t *mb_info;
|
||||
|
||||
|
@ -890,7 +900,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p
|
|||
"Unable to split H263 packet! mb_info_pos=%d mb_info_count=%d pos=%d max=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, pos, (switch_size_t)(end - buf_base));
|
||||
}
|
||||
} else {
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size);
|
||||
#else
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%ld\n", mb_info_pos, mb_info_count, mb_info_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1034,7 +1048,7 @@ static switch_status_t consume_h263_bitstream(h264_codec_context_t *context, swi
|
|||
}
|
||||
|
||||
if (!context->nalus[context->nalu_current_index].len) {
|
||||
av_packet_unref(&context->encoder_avpacket);
|
||||
av_packet_unref(context->encoder_avpacket);
|
||||
frame->m = 1;
|
||||
}
|
||||
|
||||
|
@ -1082,7 +1096,7 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw
|
|||
#endif
|
||||
|
||||
if (frame->m) {
|
||||
av_packet_unref(&context->encoder_avpacket);
|
||||
av_packet_unref(context->encoder_avpacket);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1091,7 +1105,7 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw
|
|||
|
||||
static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame)
|
||||
{
|
||||
AVPacket *pkt = &context->encoder_avpacket;
|
||||
AVPacket *pkt = context->encoder_avpacket;
|
||||
our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
|
||||
|
||||
if (!nalu->len) {
|
||||
|
@ -1291,9 +1305,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
|||
set_h264_private_data(context, aprofile);
|
||||
}
|
||||
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
avcodec_string(codec_string, sizeof(codec_string), context->encoder_ctx, 0);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
|
||||
dump_encoder_ctx(context->encoder_ctx);
|
||||
|
||||
|
@ -1393,6 +1405,8 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
|
|||
break;
|
||||
}
|
||||
|
||||
context->encoder_avpacket = av_packet_alloc();
|
||||
|
||||
switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0);
|
||||
codec->private_info = context;
|
||||
|
||||
|
@ -1417,7 +1431,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
|||
int ret;
|
||||
int *got_output = &context->got_encoded_output;
|
||||
AVFrame *avframe = NULL;
|
||||
AVPacket *pkt = &context->encoder_avpacket;
|
||||
AVPacket **pkt = &context->encoder_avpacket;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
switch_image_t *img = frame->img;
|
||||
|
@ -1440,8 +1454,8 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
|||
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);
|
||||
if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) {
|
||||
av_packet_unref(*pkt);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -1456,6 +1470,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
|||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
avctx = context->encoder_ctx;
|
||||
}
|
||||
|
||||
|
@ -1465,6 +1480,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
|||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
avctx = context->encoder_ctx;
|
||||
}
|
||||
|
||||
|
@ -1474,15 +1490,13 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
|||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
avctx = context->encoder_ctx;
|
||||
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;
|
||||
av_packet_unref(*pkt);
|
||||
/* packet data will be allocated by the encoder */
|
||||
|
||||
avframe = context->encoder_avframe;
|
||||
|
||||
|
@ -1547,14 +1561,42 @@ GCC_DIAG_ON(deprecated-declarations)
|
|||
/* encode the image */
|
||||
memset(context->nalus, 0, sizeof(context->nalus));
|
||||
context->nalu_current_index = 0;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
ret = avcodec_encode_video2(avctx, pkt, avframe, got_output);
|
||||
ret = avcodec_encode_video2(avctx, *pkt, avframe, got_output);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
|
||||
if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding Error %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
#else
|
||||
ret = avcodec_send_frame(avctx, avframe);
|
||||
|
||||
if (ret == AVERROR_EOF) {
|
||||
ret = 0;
|
||||
} else if (ret == AVERROR(EAGAIN)) {
|
||||
/* we fully drain all the output in each encode call, so this should not ever happen */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder - BUG, should never happen\n");
|
||||
ret = AVERROR_BUG;
|
||||
goto error;
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending frame to encoder\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(avctx, *pkt);
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at the moment\n");
|
||||
} else if (ret == AVERROR_EOF) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at all\n");
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error\n");
|
||||
av_packet_unref(*pkt);
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context->need_key_frame && avframe->key_frame == 1) {
|
||||
avframe->pict_type = 0;
|
||||
|
@ -1564,7 +1606,11 @@ GCC_DIAG_ON(deprecated-declarations)
|
|||
|
||||
// process:
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
if (*got_output) {
|
||||
#else
|
||||
if (ret >= 0) {
|
||||
#endif
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
*got_output = 0;
|
||||
|
@ -1572,56 +1618,66 @@ GCC_DIAG_ON(deprecated-declarations)
|
|||
if (context->av_codec_id == AV_CODEC_ID_H263) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
||||
context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)),
|
||||
*((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices);
|
||||
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)),
|
||||
*((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices);
|
||||
|
||||
#ifdef H263_MODE_B
|
||||
fs_rtp_parse_h263_rfc2190(context, pkt);
|
||||
fs_rtp_parse_h263_rfc2190(context, *pkt);
|
||||
#endif
|
||||
|
||||
context->nalu_current_index = 0;
|
||||
|
||||
return consume_nalu(context, frame);
|
||||
} else if (context->av_codec_id == AV_CODEC_ID_H263P){
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
||||
context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)),
|
||||
*((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices);
|
||||
fs_rtp_parse_h263_rfc4629(context, pkt);
|
||||
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)),
|
||||
*((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices);
|
||||
fs_rtp_parse_h263_rfc4629(context, *pkt);
|
||||
context->nalu_current_index = 0;
|
||||
|
||||
return consume_nalu(context, frame);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||
"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);
|
||||
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data +4), *got_output);
|
||||
}
|
||||
|
||||
status = switch_packetizer_feed(context->packetizer, pkt->data, pkt->size);
|
||||
status = switch_packetizer_feed(context->packetizer, (*pkt)->data, (*pkt)->size);
|
||||
if (status != SWITCH_STATUS_SUCCESS) {
|
||||
if (pkt->size > 0) {
|
||||
av_packet_unref(pkt);
|
||||
if ((*pkt)->size > 0) {
|
||||
av_packet_unref(*pkt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status = switch_packetizer_read(context->packetizer, frame);
|
||||
if (status == SWITCH_STATUS_SUCCESS && pkt->size > 0) {
|
||||
av_packet_unref(pkt);
|
||||
if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) {
|
||||
av_packet_unref(*pkt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
error:
|
||||
frame->datalen = 0;
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t *frame)
|
||||
{
|
||||
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
|
||||
AVCodecContext *avctx= context->decoder_ctx;
|
||||
switch_status_t status;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||
int ret = 0;
|
||||
#endif
|
||||
|
||||
switch_assert(frame);
|
||||
|
||||
|
@ -1654,29 +1710,57 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
|
|||
|
||||
if (frame->m) {
|
||||
uint32_t size = switch_buffer_inuse(context->nalu_buffer);
|
||||
AVPacket pkt = { 0 };
|
||||
AVPacket *pkt = NULL;
|
||||
AVFrame *picture;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
int got_picture = 0;
|
||||
int decoded_len;
|
||||
#endif
|
||||
|
||||
if (size > 0) {
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
av_init_packet(&pkt);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
pkt = av_packet_alloc();
|
||||
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;
|
||||
switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt->data);
|
||||
pkt->size = size;
|
||||
|
||||
if (!context->decoder_avframe) context->decoder_avframe = av_frame_alloc();
|
||||
picture = context->decoder_avframe;
|
||||
switch_assert(picture);
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
decoded_len = avcodec_decode_video2(avctx, picture, &got_picture, &pkt);
|
||||
decoded_len = avcodec_decode_video2(context->decoder_ctx, picture, &got_picture, pkt);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
#else
|
||||
ret = avcodec_send_packet(context->decoder_ctx, pkt);
|
||||
|
||||
if (ret == AVERROR_EOF) {
|
||||
ret = 0;
|
||||
} else if (ret == AVERROR(EAGAIN)) {
|
||||
/* we fully drain all the output in each decode call, so this should not ever happen */
|
||||
ret = AVERROR_BUG;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder BUG, should never happen\n");
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder\n");
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(context->decoder_ctx, picture);
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at the moment\n");
|
||||
} else if (ret == AVERROR_EOF) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at all\n");
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video decoding error\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer: %d got pic: %d len: %d [%dx%d]\n", size, got_picture, decoded_len, picture->width, picture->height);
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
if (got_picture && decoded_len > 0) {
|
||||
#else
|
||||
if (ret >= 0) {
|
||||
#endif
|
||||
int width = picture->width;
|
||||
int height = picture->height;
|
||||
|
||||
|
@ -1698,7 +1782,15 @@ GCC_DIAG_ON(deprecated-declarations)
|
|||
frame->img = context->img;
|
||||
}
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
av_frame_unref(picture);
|
||||
av_packet_free(&pkt);
|
||||
}
|
||||
|
||||
switch_buffer_zero(context->nalu_buffer);
|
||||
|
@ -1791,6 +1883,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
|
|||
av_frame_free(&context->decoder_avframe);
|
||||
}
|
||||
|
||||
if (context->encoder_avpacket) {
|
||||
av_packet_free(&context->encoder_avpacket);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1818,8 +1914,10 @@ static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
|
|||
#endif
|
||||
if (prev->id == id &&
|
||||
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,6 +25,7 @@
|
|||
*
|
||||
* Seven Du <dujinfang@gmail.com>
|
||||
* Anthony Minessale <anthm@freeswitch.org>
|
||||
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||
*
|
||||
* mod_av -- FS Video Codec / File Format using libav.org
|
||||
*
|
||||
|
@ -49,6 +50,7 @@ typedef struct av_mutex_helper_s {
|
|||
switch_memory_pool_t *pool;
|
||||
} av_mutex_helper_t;
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
||||
{
|
||||
av_mutex_helper_t *context = NULL;
|
||||
|
@ -93,6 +95,7 @@ int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef AV_LOG_TRACE
|
||||
#define AV_LOG_TRACE 96
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
||||
* Raymond Chandler <intralanman@gmail.com>
|
||||
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
||||
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||
*
|
||||
*
|
||||
* mod_av.h -- LibAV mod
|
||||
|
@ -39,6 +40,10 @@
|
|||
#ifndef MOD_AV_H
|
||||
#define MOD_AV_H
|
||||
|
||||
#define LIBAVCODEC_V 59
|
||||
#define LIBAVFORMAT_V 59
|
||||
#define LIBAVUTIL_V 57
|
||||
|
||||
struct mod_av_globals {
|
||||
int debug;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue