/** * Figure out the mime-type for the muxed data stream */ static const char* lav_muxer_mime(muxer_t* m, const struct streaming_start *ss) { int i; int has_audio; int has_video; const streaming_start_component_t *ssc; has_audio = 0; has_video = 0; for(i=0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; if(ssc->ssc_disabled) continue; if(!lav_muxer_support_stream(m->m_container, ssc->ssc_type)) continue; has_video |= SCT_ISVIDEO(ssc->ssc_type); has_audio |= SCT_ISAUDIO(ssc->ssc_type); } if(has_video) return muxer_container_type2mime(m->m_container, 1); else if(has_audio) return muxer_container_type2mime(m->m_container, 0); else return muxer_container_type2mime(MC_UNKNOWN, 0); }
/** * Init the muxer with streams */ static int lav_muxer_init(muxer_t* m, const struct streaming_start *ss, const char *name) { int i; const streaming_start_component_t *ssc; AVFormatContext *oc; lav_muxer_t *lm = (lav_muxer_t*)m; char app[128]; snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version); oc = lm->lm_oc; av_dict_set(&oc->metadata, "title", name, 0); av_dict_set(&oc->metadata, "service_name", name, 0); av_dict_set(&oc->metadata, "service_provider", app, 0); if(lm->m_container == MC_MPEGTS) lm->lm_h264_filter = av_bitstream_filter_init("h264_mp4toannexb"); oc->max_delay = 0.7 * AV_TIME_BASE; for(i=0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; if(ssc->ssc_disabled) continue; if(!lav_muxer_support_stream(lm->m_container, ssc->ssc_type)) { tvhlog(LOG_WARNING, "libav", "%s is not supported in %s", streaming_component_type2txt(ssc->ssc_type), muxer_container_type2txt(lm->m_container)); continue; } if(lav_muxer_add_stream(lm, ssc)) { tvhlog(LOG_ERR, "libav", "Failed to add %s stream", streaming_component_type2txt(ssc->ssc_type)); continue; } } if(!lm->lm_oc->nb_streams) { tvhlog(LOG_ERR, "libav", "No supported streams available"); lm->m_errors++; return -1; } else if(avformat_write_header(lm->lm_oc, NULL) < 0) { tvhlog(LOG_ERR, "libav", "Failed to write %s header", muxer_container_type2txt(lm->m_container)); lm->m_errors++; return -1; } lm->lm_init = 1; return 0; }
/** * Init the muxer with streams */ static int lav_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name) { int i; streaming_start_component_t *ssc; AVFormatContext *oc; AVDictionary *opts = NULL; lav_muxer_t *lm = (lav_muxer_t*)m; char app[128]; snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version); oc = lm->lm_oc; av_dict_set(&oc->metadata, "title", name, 0); 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"); } oc->max_delay = 0.7 * AV_TIME_BASE; for(i=0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; if(ssc->ssc_disabled) continue; if(!lav_muxer_support_stream(lm->m_config.m_type, ssc->ssc_type)) { tvhwarn(LS_LIBAV, "%s is not supported in %s", streaming_component_type2txt(ssc->ssc_type), muxer_container_type2txt(lm->m_config.m_type)); ssc->ssc_muxer_disabled = 1; continue; } if(lav_muxer_add_stream(lm, ssc)) { tvherror(LS_LIBAV, "Failed to add %s stream", streaming_component_type2txt(ssc->ssc_type)); ssc->ssc_muxer_disabled = 1; continue; } } if(lm->m_config.m_type == MC_AVMP4) { av_dict_set(&opts, "frag_duration", "1", 0); av_dict_set(&opts, "ism_lookahead", "0", 0); } if(!lm->lm_oc->nb_streams) { tvherror(LS_LIBAV, "No supported streams available"); lm->m_errors++; return -1; } 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; } if (opts) av_dict_free(&opts); lm->lm_init = 1; return 0; }