diff --git a/daemon/codec.c b/daemon/codec.c index a1b5f0fa3..24a312456 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1066,7 +1066,7 @@ static int packet_encoded_t38(encoder_t *enc, void *u1, void *u2) { return 0; return t38_gateway_input_samples(mp->media->t38_gateway, - (int16_t *) enc->avpkt.data, enc->avpkt.size / 2); + (int16_t *) enc->avpkt->data, enc->avpkt->size / 2); } static void __generator_stop(struct call_media *media) { @@ -2913,14 +2913,14 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { //unsigned int seq_off = (mp->iter_out > mp->iter_in) ? 1 : 0; ilogs(transcoding, LOG_DEBUG, "RTP media successfully encoded: TS %llu, len %i", - (unsigned long long) enc->avpkt.pts, enc->avpkt.size); + (unsigned long long) enc->avpkt->pts, enc->avpkt->size); // run this through our packetizer - AVPacket *in_pkt = &enc->avpkt; + AVPacket *in_pkt = enc->avpkt; while (1) { // figure out how big of a buffer we need - unsigned int payload_len = MAX(MAX(enc->avpkt.size, ch->bytes_per_packet), + unsigned int payload_len = MAX(MAX(enc->avpkt->size, ch->bytes_per_packet), sizeof(struct telephone_event_payload)); unsigned int pkt_len = sizeof(struct rtp_header) + payload_len + RTP_BUFFER_TAIL_ROOM; // prepare our buffers @@ -2935,7 +2935,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { int ret = enc->def->packetizer(in_pkt, ch->sample_buffer, &inout, enc); - if (G_UNLIKELY(ret == -1 || enc->avpkt.pts == AV_NOPTS_VALUE)) { + if (G_UNLIKELY(ret == -1 || enc->avpkt->pts == AV_NOPTS_VALUE)) { // nothing free(buf); break; @@ -2948,7 +2948,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { unsigned int repeats = 0; int payload_type = -1; - int is_dtmf = dtmf_event_payload(&inout, (uint64_t *) &enc->avpkt.pts, enc->avpkt.duration, + int is_dtmf = dtmf_event_payload(&inout, (uint64_t *) &enc->avpkt->pts, enc->avpkt->duration, &ch->dtmf_event, &ch->dtmf_events); if (is_dtmf) { payload_type = ch->handler->dtmf_payload_type; @@ -2958,7 +2958,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { repeats = 2; // DTMF end event } else { - if (is_silence_event(&inout, &ch->silence_events, enc->avpkt.pts, enc->avpkt.duration)) + if (is_silence_event(&inout, &ch->silence_events, enc->avpkt->pts, enc->avpkt->duration)) payload_type = ch->handler->cn_payload_type; } @@ -2972,7 +2972,7 @@ static int packet_encoded_rtp(encoder_t *enc, void *u1, void *u2) { memcpy(send_buf, buf, pkt_len); } __output_rtp(mp, ch, ch->handler, send_buf, inout.len, ch->first_ts - + enc->avpkt.pts / enc->def->clockrate_mult, + + enc->avpkt->pts / enc->def->clockrate_mult, ch->rtp_mark ? 1 : 0, -1, 0, payload_type, 0); mp->ssrc_out->parent->seq_diff++; diff --git a/daemon/media_player.c b/daemon/media_player.c index 1d29ac816..30aae353e 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -98,6 +98,7 @@ static void __media_player_free(void *p) { ssrc_ctx_put(&mp->ssrc_out); mutex_destroy(&mp->lock); obj_put(mp->call); + av_packet_free(&mp->pkt); } #endif @@ -124,9 +125,9 @@ struct media_player *media_player_new(struct call_monologue *ml) { mp->seq = ssl_random(); mp->ssrc_out = ssrc_ctx; - av_init_packet(&mp->pkt); - mp->pkt.data = NULL; - mp->pkt.size = 0; + mp->pkt = av_packet_alloc(); + mp->pkt->data = NULL; + mp->pkt->size = 0; return mp; #else @@ -388,7 +389,7 @@ static void media_player_read_packet(struct media_player *mp) { if (!mp->fmtctx) return; - int ret = av_read_frame(mp->fmtctx, &mp->pkt); + int ret = av_read_frame(mp->fmtctx, mp->pkt); if (ret < 0) { if (ret == AVERROR_EOF) { if (mp->repeat > 1){ @@ -400,7 +401,7 @@ static void media_player_read_packet(struct media_player *mp) { ret = av_seek_frame(mp->fmtctx, -1, 0, 0); if (ret < 0) ilog(LOG_ERR, "Failed to seek to beginning of media file"); - ret = av_read_frame(mp->fmtctx, &mp->pkt); + ret = av_read_frame(mp->fmtctx, mp->pkt); } else { ilog(LOG_DEBUG, "EOF reading from media stream"); return; @@ -431,26 +432,26 @@ static void media_player_read_packet(struct media_player *mp) { // scale pts and duration according to sample rate - long long duration_scaled = mp->pkt.duration * avs->CODECPAR->sample_rate + long long duration_scaled = mp->pkt->duration * avs->CODECPAR->sample_rate * avs->time_base.num / avs->time_base.den; - unsigned long long pts_scaled = mp->pkt.pts * avs->CODECPAR->sample_rate + unsigned long long pts_scaled = mp->pkt->pts * avs->CODECPAR->sample_rate * avs->time_base.num / avs->time_base.den; - long long us_dur = mp->pkt.duration * 1000000LL * avs->time_base.num / avs->time_base.den; + long long us_dur = mp->pkt->duration * 1000000LL * avs->time_base.num / avs->time_base.den; ilog(LOG_DEBUG, "read media packet: pts %llu duration %lli (scaled %llu/%lli, %lli us), " "sample rate %i, time_base %i/%i", - (unsigned long long) mp->pkt.pts, - (long long) mp->pkt.duration, + (unsigned long long) mp->pkt->pts, + (long long) mp->pkt->duration, pts_scaled, duration_scaled, us_dur, avs->CODECPAR->sample_rate, avs->time_base.num, avs->time_base.den); - media_player_add_packet(mp, (char *) mp->pkt.data, mp->pkt.size, us_dur, pts_scaled); + media_player_add_packet(mp, (char *) mp->pkt->data, mp->pkt->size, us_dur, pts_scaled); out: - av_packet_unref(&mp->pkt); + av_packet_unref(mp->pkt); } diff --git a/include/media_player.h b/include/media_player.h index bf8f5693a..53bdeca73 100644 --- a/include/media_player.h +++ b/include/media_player.h @@ -43,7 +43,7 @@ struct media_player { AVFormatContext *fmtctx; unsigned long duration; // in milliseconds - AVPacket pkt; + AVPacket *pkt; struct codec_handler *handler; struct ssrc_ctx *ssrc_out; unsigned long seq; diff --git a/lib/codeclib.c b/lib/codeclib.c index f13f5f4a1..afc29f743 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -590,6 +590,8 @@ static const char *avc_decoder_init(decoder_t *dec, const str *fmtp, const str * if (!codec) return "codec not supported"; + dec->u.avc.avpkt = av_packet_alloc(); + dec->u.avc.avcctx = avcodec_alloc_context3(codec); if (!dec->u.avc.avcctx) return "failed to alloc codec context"; @@ -663,8 +665,6 @@ decoder_t *decoder_new_fmtp(const codec_def_t *def, int clockrate, int channels, if (err) goto err; - av_init_packet(&ret->u.avc.avpkt); - ret->pts = (uint64_t) -1LL; ret->rtp_ts = (unsigned long) -1L; @@ -722,6 +722,7 @@ static void avc_decoder_close(decoder_t *dec) { avcodec_close(dec->u.avc.avcctx); av_free(dec->u.avc.avcctx); #endif + av_packet_free(&dec->u.avc.avpkt); } @@ -744,9 +745,9 @@ static int avc_decoder_input(decoder_t *dec, const str *data, GQueue *out) { const char *err; int av_ret = 0; - dec->u.avc.avpkt.data = (unsigned char *) data->s; - dec->u.avc.avpkt.size = data->len; - dec->u.avc.avpkt.pts = dec->pts; + dec->u.avc.avpkt->data = (unsigned char *) data->s; + dec->u.avc.avpkt->size = data->len; + dec->u.avc.avpkt->pts = dec->pts; AVFrame *frame = NULL; @@ -761,13 +762,13 @@ static int avc_decoder_input(decoder_t *dec, const str *data, GQueue *out) { goto err; #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 36, 0) - if (dec->u.avc.avpkt.size) { - av_ret = avcodec_send_packet(dec->u.avc.avcctx, &dec->u.avc.avpkt); + if (dec->u.avc.avpkt->size) { + av_ret = avcodec_send_packet(dec->u.avc.avcctx, dec->u.avc.avpkt); cdbg("send packet ret %i", av_ret); err = "failed to send packet to avcodec"; if (av_ret == 0) { // consumed the packet - dec->u.avc.avpkt.size = 0; + dec->u.avc.avpkt->size = 0; keep_going = 1; } else { @@ -794,10 +795,10 @@ static int avc_decoder_input(decoder_t *dec, const str *data, GQueue *out) { } #else // only do this if we have any input left - if (dec->u.avc.avpkt.size == 0) + if (dec->u.avc.avpkt->size == 0) break; - av_ret = avcodec_decode_audio4(dec->u.avc.avcctx, frame, &got_frame, &dec->u.avc.avpkt); + av_ret = avcodec_decode_audio4(dec->u.avc.avcctx, frame, &got_frame, dec->u.avc.avpkt); cdbg("decode frame ret %i, got frame %i", av_ret, got_frame); err = "failed to decode audio packet"; if (av_ret < 0) @@ -805,10 +806,10 @@ static int avc_decoder_input(decoder_t *dec, const str *data, GQueue *out) { if (av_ret > 0) { // consumed some input err = "invalid return value"; - if (av_ret > dec->u.avc.avpkt.size) + if (av_ret > dec->u.avc.avpkt->size) goto err; - dec->u.avc.avpkt.size -= av_ret; - dec->u.avc.avpkt.data += av_ret; + dec->u.avc.avpkt->size -= av_ret; + dec->u.avc.avpkt->data += av_ret; keep_going = 1; } if (got_frame) @@ -823,8 +824,8 @@ static int avc_decoder_input(decoder_t *dec, const str *data, GQueue *out) { frame->pts = frame->pkt_pts; #endif if (G_UNLIKELY(frame->pts == AV_NOPTS_VALUE)) - frame->pts = dec->u.avc.avpkt.pts; - dec->u.avc.avpkt.pts += frame->nb_samples; + frame->pts = dec->u.avc.avpkt->pts; + dec->u.avc.avpkt->pts += frame->nb_samples; g_queue_push_tail(out, frame); frame = NULL; @@ -1311,7 +1312,7 @@ int encoder_config_fmtp(encoder_t *enc, const codec_def_t *def, int bitrate, int if (err) goto err; - av_init_packet(&enc->avpkt); + enc->avpkt = av_packet_alloc(); // output frame and fifo enc->frame = av_frame_alloc(); @@ -1370,6 +1371,7 @@ void encoder_close(encoder_t *enc) { } void encoder_free(encoder_t *enc) { encoder_close(enc); + av_packet_free(&enc->avpkt); g_slice_free1(sizeof(*enc), enc); } @@ -1398,7 +1400,7 @@ static int avc_encoder_input(encoder_t *enc, AVFrame **frame) { } } - av_ret = avcodec_receive_packet(enc->u.avc.avcctx, &enc->avpkt); + av_ret = avcodec_receive_packet(enc->u.avc.avcctx, enc->avpkt); cdbg("receive packet ret %i", av_ret); if (av_ret == 0) { // got some data @@ -1415,7 +1417,7 @@ static int avc_encoder_input(encoder_t *enc, AVFrame **frame) { if (!*frame) return 0; - av_ret = avcodec_encode_audio2(enc->u.avc.avcctx, &enc->avpkt, *frame, &got_packet); + av_ret = avcodec_encode_audio2(enc->u.avc.avcctx, enc->avpkt, *frame, &got_packet); cdbg("encode frame ret %i, got packet %i", av_ret, got_packet); if (av_ret == 0) *frame = NULL; // consumed @@ -1428,16 +1430,16 @@ static int avc_encoder_input(encoder_t *enc, AVFrame **frame) { if (!got_packet) return keep_going; - cdbg("output avpkt size is %i", (int) enc->avpkt.size); - cdbg("output pkt pts/dts is %li/%li", (long) enc->avpkt.pts, - (long) enc->avpkt.dts); + cdbg("output avpkt size is %i", (int) enc->avpkt->size); + cdbg("output pkt pts/dts is %li/%li", (long) enc->avpkt->pts, + (long) enc->avpkt->dts); // the encoder may return frames with the same dts multiple consecutive times. // the muxer may not like this, so ensure monotonically increasing dts. - if (enc->mux_dts > enc->avpkt.dts) - enc->avpkt.dts = enc->mux_dts; - if (enc->avpkt.pts < enc->avpkt.dts) - enc->avpkt.pts = enc->avpkt.dts; + if (enc->mux_dts > enc->avpkt->dts) + enc->avpkt->dts = enc->mux_dts; + if (enc->avpkt->pts < enc->avpkt->dts) + enc->avpkt->pts = enc->avpkt->dts; return keep_going; @@ -1450,7 +1452,7 @@ err: int encoder_input_data(encoder_t *enc, AVFrame *frame, int (*callback)(encoder_t *, void *u1, void *u2), void *u1, void *u2) { - enc->avpkt.size = 0; + enc->avpkt->size = 0; while (1) { if (!enc->def->codec_type->encoder_input) @@ -1460,22 +1462,22 @@ int encoder_input_data(encoder_t *enc, AVFrame *frame, if (ret < 0) return -1; - if (enc->avpkt.size) { + if (enc->avpkt->size) { // don't rely on the encoder producing steady timestamps, // instead keep track of them ourselves based on the returned // frame duration - enc->avpkt.pts = enc->next_pts; + enc->avpkt->pts = enc->next_pts; if (enc->def->codec_type->encoder_got_packet) enc->def->codec_type->encoder_got_packet(enc); callback(enc, u1, u2); - enc->next_pts += enc->avpkt.duration; - enc->mux_dts = enc->avpkt.dts + 1; // min next expected dts + enc->next_pts += enc->avpkt->duration; + enc->mux_dts = enc->avpkt->dts + 1; // min next expected dts - av_packet_unref(&enc->avpkt); - enc->avpkt.size = 0; + av_packet_unref(enc->avpkt); + enc->avpkt->size = 0; } if (ret == 0) @@ -1550,7 +1552,7 @@ static int packetizer_samplestream(AVPacket *pkt, GString *buf, str *input_outpu memcpy(input_output->s, buf->str, input_output->len); g_string_erase(buf, 0, input_output->len); // adjust output pts - enc->avpkt.pts = enc->packet_pts; + enc->avpkt->pts = enc->packet_pts; enc->packet_pts += input_output->len * (enc->def->bits_per_sample * enc->def->clockrate_mult / 8); return buf->len >= input_output->len ? 1 : 0; } @@ -2339,8 +2341,8 @@ static int generic_silence_dtx(decoder_t *dec, GQueue *out, int ptime) { memset(frame->extended_data[0], 0, frame->linesize[0]); // advance PTS - frame->pts = dec->u.avc.avpkt.pts; - dec->u.avc.avpkt.pts += frame->nb_samples; + frame->pts = dec->u.avc.avpkt->pts; + dec->u.avc.avpkt->pts += frame->nb_samples; g_queue_push_tail(out, frame); @@ -2454,17 +2456,17 @@ static int bcg729_encoder_input(encoder_t *enc, AVFrame **frame) { return -1; } - av_new_packet(&enc->avpkt, 10); + av_new_packet(enc->avpkt, 10); unsigned char len = 0; - bcg729Encoder(enc->u.bcg729, (void *) (*frame)->extended_data[0], enc->avpkt.data, &len); + bcg729Encoder(enc->u.bcg729, (void *) (*frame)->extended_data[0], enc->avpkt->data, &len); if (!len) { - av_packet_unref(&enc->avpkt); + av_packet_unref(enc->avpkt); return 0; } - enc->avpkt.size = len; - enc->avpkt.pts = (*frame)->pts; + enc->avpkt->size = len; + enc->avpkt->pts = (*frame)->pts; return 0; } diff --git a/lib/codeclib.h b/lib/codeclib.h index ed698e367..9ea719d22 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -212,7 +212,7 @@ struct decoder_s { union { struct { AVCodecContext *avcctx; - AVPacket avpkt; + AVPacket *avpkt; union { struct { @@ -265,7 +265,7 @@ struct encoder_s { bcg729EncoderChannelContextStruct *bcg729; #endif } u; - AVPacket avpkt; + AVPacket *avpkt; AVAudioFifo *fifo; int64_t fifo_pts; // pts of first data in fifo int64_t packet_pts; // first pts of data in packetizer buffer diff --git a/recording-daemon/output.c b/recording-daemon/output.c index 2797098ca..166c09e89 100644 --- a/recording-daemon/output.c +++ b/recording-daemon/output.c @@ -27,12 +27,12 @@ static int output_shutdown(output_t *output); static int output_got_packet(encoder_t *enc, void *u1, void *u2) { output_t *output = u1; - dbg("{%s%s%s} output avpkt size is %i", FMT_M(output->file_name), (int) enc->avpkt.size); - dbg("{%s%s%s} output pkt pts/dts is %li/%li", FMT_M(output->file_name), (long) enc->avpkt.pts, - (long) enc->avpkt.dts); + dbg("{%s%s%s} output avpkt size is %i", FMT_M(output->file_name), (int) enc->avpkt->size); + dbg("{%s%s%s} output pkt pts/dts is %li/%li", FMT_M(output->file_name), (long) enc->avpkt->pts, + (long) enc->avpkt->dts); dbg("{%s%s%s} output dts %li", FMT_M(output->file_name), (long) output->encoder->mux_dts); - av_write_frame(output->fmtctx, &enc->avpkt); + av_write_frame(output->fmtctx, enc->avpkt); return 0; }