typedef struct lav_muxer {
muxer_t;
AVFormatContext *lm_oc;
- AVBitStreamFilterContext *lm_h264_filter;
- AVBitStreamFilterContext *lm_hevc_filter;
+ AVBSFContext *ctx;
+ const AVBitStreamFilter *bsf_h264_filter;
+ const AVBitStreamFilter *bsf_hevc_filter;
+ const AVBitStreamFilter *bsf_vp9_filter;
int lm_fd;
int lm_init;
} lav_muxer_t;
{
AVStream *st;
AVCodecContext *c;
- AVCodec *codec;
+ const AVCodec *codec;
+ int rc = -1;
st = avformat_new_stream(lm->lm_oc, NULL);
if (!st)
st->sample_aspect_ratio.num = c->sample_aspect_ratio.num;
st->sample_aspect_ratio.den = c->sample_aspect_ratio.den;
+ if (ssc->es_type == SCT_H264) {
+ if (av_bsf_alloc(lm->bsf_h264_filter, &lm->ctx)) {
+ tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for h264_mp4toannexb");
+ goto fail;
+ }
+ }
+ else if (ssc->es_type == SCT_HEVC) {
+ if (av_bsf_alloc(lm->bsf_hevc_filter, &lm->ctx)) {
+ tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for hevc_mp4toannexb");
+ goto fail;
+ }
+ }
+ else if (ssc->es_type == SCT_VP9) {
+ if (av_bsf_alloc(lm->bsf_vp9_filter, &lm->ctx)) {
+ tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for vp9_superframe ");
+ goto fail;
+ }
+ }
+ else {
+ if (av_bsf_alloc(lm->bsf_h264_filter, &lm->ctx)) {
+ tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for h264_mp4toannexb");
+ goto fail;
+ }
+ }
+ if(avcodec_parameters_copy(lm->ctx->par_in, st->codecpar)) {
+ tvherror(LS_LIBAV, "Failed to copy paramters to AVBSFContext");
+ goto fail;
+ }
+ lm->ctx->time_base_in = st->time_base;
+ if (av_bsf_init(lm->ctx)) {
+ tvherror(LS_LIBAV, "Failed to init AVBSFContext");
+ goto fail;
+ }
} else if(SCT_ISSUBTITLE(ssc->es_type)) {
c->codec_type = AVMEDIA_TYPE_SUBTITLE;
avcodec_parameters_from_context(st->codecpar, c);
if(lm->lm_oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
+ rc = 0;
- avcodec_parameters_from_context(st->codecpar, c);
+fail:
+ av_freep(&c->extradata);
avcodec_free_context(&c);
- return 0;
+ return rc;
}
char app[128];
AVOutputFormat *fmt;
const char *muxer_name;
+ int rc = -1;
snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version);
av_dict_set(&oc->metadata, "service_name", name, 0);
av_dict_set(&oc->metadata, "service_provider", app, 0);
- if(lm->m_config.m_type == MC_MPEGTS) {
- lm->lm_h264_filter = av_bitstream_filter_init("h264_mp4toannexb");
- lm->lm_hevc_filter = av_bitstream_filter_init("hevc_mp4toannexb");
+ lm->bsf_h264_filter = av_bsf_get_by_name("h264_mp4toannexb");
+ if (lm->bsf_h264_filter == NULL) {
+ tvhwarn(LS_LIBAV, "Failed to get BSF: h264_mp4toannexb");
+ }
+ lm->bsf_hevc_filter = av_bsf_get_by_name("hevc_mp4toannexb");
+ if (lm->bsf_h264_filter == NULL) {
+ tvhwarn(LS_LIBAV, "Failed to get BSF: hevc_mp4toannexb");
+ }
+ lm->bsf_vp9_filter = av_bsf_get_by_name("vp9_superframe");
+ if (lm->bsf_vp9_filter == NULL) {
+ tvhwarn(LS_LIBAV, "Failed to get BSF: vp9_superframe ");
}
oc->max_delay = 0.7 * AV_TIME_BASE;
if(!lm->lm_oc->nb_streams) {
tvherror(LS_LIBAV, "No supported streams available");
lm->m_errors++;
- return -1;
+ goto fail;
} else if(avformat_write_header(lm->lm_oc, &opts) < 0) {
tvherror(LS_LIBAV, "Failed to write %s header",
muxer_container_type2txt(lm->m_config.m_type));
lm->m_errors++;
- return -1;
+ goto fail;
}
+ lm->lm_init = 1;
+ rc = 0;
+
+fail:
if (opts)
av_dict_free(&opts);
- lm->lm_init = 1;
-
- return 0;
+ return rc;
}
lm->lm_fd = -1;
oc = lm->lm_oc;
- snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
if((r = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) {
av_strerror(r, buf, sizeof(buf));
tofree = NULL;
av_init_packet(&packet);
- codec_id = st->codec->codec_id;
-
- if((lm->lm_h264_filter && codec_id == AV_CODEC_ID_H264) ||
- (lm->lm_hevc_filter && codec_id == AV_CODEC_ID_HEVC)) {
- pkt = avc_convert_pkt(opkt = pkt);
- pkt_ref_dec(opkt);
- if(av_bitstream_filter_filter(st->codec->codec_id == AV_CODEC_ID_H264 ?
- lm->lm_h264_filter : lm->lm_hevc_filter,
- st->codec,
- NULL,
- &packet.data,
- &packet.size,
- pktbuf_ptr(pkt->pkt_payload),
- pktbuf_len(pkt->pkt_payload),
- SCT_ISVIDEO(pkt->pkt_type) ? pkt->v.pkt_frametype < PKT_P_FRAME : 1) < 0) {
- tvhwarn(LS_LIBAV, "Failed to filter bitstream");
- if (packet.data != pktbuf_ptr(pkt->pkt_payload))
- av_free(packet.data);
- break;
- } else {
- tofree = packet.data;
- }
- } else if (codec_id == AV_CODEC_ID_AAC) {
+ codec_id = st->codecpar->codec_id;
+
+ if (codec_id == AV_CODEC_ID_AAC) {
/* remove ADTS header */
packet.data = pktbuf_ptr(pkt->pkt_payload) + 7;
packet.size = pktbuf_len(pkt->pkt_payload) - 7;
int i;
lav_muxer_t *lm = (lav_muxer_t*)m;
- if(lm->lm_h264_filter)
- av_bitstream_filter_close(lm->lm_h264_filter);
-
- if(lm->lm_hevc_filter)
- av_bitstream_filter_close(lm->lm_hevc_filter);
+ if(lm->ctx){
+ if (av_bsf_send_packet(lm->ctx, NULL))
+ tvhwarn(LS_LIBAV, "Failed to send packet to AVBSFContext (close)");
+ av_bsf_free(&lm->ctx);
+ }
if (lm->lm_oc) {
for(i=0; i<lm->lm_oc->nb_streams; i++)
- av_freep(&lm->lm_oc->streams[i]->codec->extradata);
+ av_freep(&lm->lm_oc->streams[i]->codecpar->extradata);
}
if(lm->lm_oc) {