/** * Add a stream to the muxer */ static int lav_muxer_add_stream(lav_muxer_t *lm, const streaming_start_component_t *ssc) { AVStream *st; AVCodecContext *c; st = avformat_new_stream(lm->lm_oc, NULL); if (!st) return -1; st->id = ssc->ssc_index; c = st->codec; c->codec_id = streaming_component_type2codec_id(ssc->ssc_type); switch(lm->m_container) { case MC_MATROSKA: st->time_base.num = 1000000; st->time_base.den = 1; break; case MC_MPEGPS: c->rc_buffer_size = 224*1024*8; //Fall-through case MC_MPEGTS: st->time_base.num = 90000; st->time_base.den = 1; break; default: st->time_base = AV_TIME_BASE_Q; break; } if(ssc->ssc_gh) { c->extradata_size = pktbuf_len(ssc->ssc_gh); c->extradata = av_malloc(c->extradata_size); memcpy(c->extradata, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } if(SCT_ISAUDIO(ssc->ssc_type)) { c->codec_type = AVMEDIA_TYPE_AUDIO; c->sample_fmt = AV_SAMPLE_FMT_S16; c->sample_rate = sri_to_rate(ssc->ssc_sri); c->channels = ssc->ssc_channels; c->time_base.num = 1; c->time_base.den = c->sample_rate; av_dict_set(&st->metadata, "language", ssc->ssc_lang, 0); } else if(SCT_ISVIDEO(ssc->ssc_type)) { c->codec_type = AVMEDIA_TYPE_VIDEO; c->width = ssc->ssc_width; c->height = ssc->ssc_height; c->time_base.num = 1; c->time_base.den = 25; c->sample_aspect_ratio.num = ssc->ssc_aspect_num; c->sample_aspect_ratio.den = ssc->ssc_aspect_den; st->sample_aspect_ratio.num = c->sample_aspect_ratio.num; st->sample_aspect_ratio.den = c->sample_aspect_ratio.den; } else if(SCT_ISSUBTITLE(ssc->ssc_type)) { c->codec_type = AVMEDIA_TYPE_SUBTITLE; av_dict_set(&st->metadata, "language", ssc->ssc_lang, 0); } if(lm->lm_oc->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= CODEC_FLAG_GLOBAL_HEADER; return 0; }
/** * Add a stream to the muxer */ static int lav_muxer_add_stream(lav_muxer_t *lm, const streaming_start_component_t *ssc) { AVStream *st; AVCodecContext *c; st = avformat_new_stream(lm->lm_oc, NULL); if (!st) return -1; st->id = ssc->ssc_index; c = st->codec; c->codec_id = streaming_component_type2codec_id(ssc->ssc_type); switch(lm->m_config.m_type) { case MC_MATROSKA: case MC_AVMATROSKA: case MC_AVMP4: st->time_base.num = 1000000; st->time_base.den = 1; break; case MC_MPEGPS: c->rc_buffer_size = 224*1024*8; //Fall-through case MC_MPEGTS: st->time_base.num = 90000; st->time_base.den = 1; break; default: st->time_base = AV_TIME_BASE_Q; break; } if(ssc->ssc_gh) { if (ssc->ssc_type == SCT_H264 || ssc->ssc_type == SCT_HEVC) { sbuf_t hdr; sbuf_init(&hdr); if (ssc->ssc_type == SCT_H264) { isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } else { isom_write_hvcc(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } c->extradata_size = hdr.sb_ptr; c->extradata = av_malloc(hdr.sb_ptr); memcpy(c->extradata, hdr.sb_data, hdr.sb_ptr); sbuf_free(&hdr); } else { c->extradata_size = pktbuf_len(ssc->ssc_gh); c->extradata = av_malloc(c->extradata_size); memcpy(c->extradata, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } } if(SCT_ISAUDIO(ssc->ssc_type)) { c->codec_type = AVMEDIA_TYPE_AUDIO; c->sample_fmt = AV_SAMPLE_FMT_S16; c->sample_rate = sri_to_rate(ssc->ssc_sri); c->channels = ssc->ssc_channels; #if 0 c->time_base.num = 1; c->time_base.den = c->sample_rate; #else c->time_base = st->time_base; #endif av_dict_set(&st->metadata, "language", ssc->ssc_lang, 0); } else if(SCT_ISVIDEO(ssc->ssc_type)) { c->codec_type = AVMEDIA_TYPE_VIDEO; c->width = ssc->ssc_width; c->height = ssc->ssc_height; c->time_base.num = 1; c->time_base.den = 25; c->sample_aspect_ratio.num = ssc->ssc_aspect_num; c->sample_aspect_ratio.den = ssc->ssc_aspect_den; if (lm->m_config.m_type == MC_AVMP4) { /* this is a whole hell */ AVRational ratio = { c->height, c->width }; c->sample_aspect_ratio = av_mul_q(c->sample_aspect_ratio, ratio); } st->sample_aspect_ratio.num = c->sample_aspect_ratio.num; st->sample_aspect_ratio.den = c->sample_aspect_ratio.den; } else if(SCT_ISSUBTITLE(ssc->ssc_type)) { c->codec_type = AVMEDIA_TYPE_SUBTITLE; av_dict_set(&st->metadata, "language", ssc->ssc_lang, 0); } if(lm->lm_oc->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= CODEC_FLAG_GLOBAL_HEADER; return 0; }