@@ -34,7 +34,7 @@ static GF_Err avc_import_ffextradata(const u8 *extradata, const u64 extradataSiz
3434 }
3535 if (gf_bs_read_u32 (bs) != 0x00000001 ) {
3636 gf_bs_del (bs);
37- return GF_BAD_PARAM ;
37+ return GF_NON_COMPLIANT_BITSTREAM ;
3838 }
3939
4040 // SPS
@@ -151,7 +151,7 @@ static GF_Err hevc_import_ffextradata(const u8 *extradata, const u64 extradata_s
151151
152152 if (gf_bs_read_u32 (bs) != 0x00000001 ) {
153153 gf_bs_del (bs);
154- return GF_BAD_PARAM ;
154+ return GF_NON_COMPLIANT_BITSTREAM ;
155155 }
156156 NALStart = gf_bs_get_position (bs);
157157 NALSize = gf_media_nalu_next_start_code_bs (bs);
@@ -314,6 +314,7 @@ void fillVideoSampleData(const u8 *bufPtr, u32 bufLen, GF_ISOSample &sample) {
314314 bufPtr += (NALUSize + scSize);
315315 bufLen -= (NALUSize + scSize);
316316 }
317+
317318 while (bufLen) {
318319 NALUSize = gf_media_nalu_next_start_code (bufPtr, bufLen, &scSize);
319320 if (NALUSize != 0 ) {
@@ -570,22 +571,6 @@ void GPACMuxMP4::declareStreamAudio(std::shared_ptr<const MetadataPktLibavAudio>
570571}
571572
572573void GPACMuxMP4::declareStreamVideo (std::shared_ptr<const MetadataPktLibavVideo> metadata) {
573- GF_AVCConfig *avccfg = gf_odf_avc_cfg_new ();
574- if (!avccfg) {
575- Log::msg (Log::Warning, " Cannot create AVCConfig" );
576- throw std::runtime_error (" [GPACMuxMP4] Container format import failed" );
577- }
578-
579- const uint8_t *extradata;
580- size_t extradataSize;
581- metadata->getExtradata (extradata, extradataSize);
582- GF_Err e = avc_import_ffextradata (extradata, extradataSize, avccfg);
583- if (e) {
584- Log::msg (Log::Warning, " Cannot parse H264 SPS/PPS" );
585- gf_odf_avc_cfg_del (avccfg);
586- throw std::runtime_error (" [GPACMuxMP4] Container format import failed" );
587- }
588-
589574 u32 trackNum = gf_isom_new_track (m_iso, 0 , GF_ISOM_MEDIA_VISUAL, metadata->getTimeScale () * TIMESCALE_MUL);
590575 if (!trackNum) {
591576 Log::msg (Log::Warning, " Cannot create new track" );
@@ -594,20 +579,74 @@ void GPACMuxMP4::declareStreamVideo(std::shared_ptr<const MetadataPktLibavVideo>
594579
595580 m_trackId = gf_isom_get_track_id (m_iso, trackNum);
596581
597- e = gf_isom_set_track_enabled (m_iso, trackNum, GF_TRUE);
582+ GF_Err e = gf_isom_set_track_enabled (m_iso, trackNum, GF_TRUE);
598583 if (e != GF_OK) {
599584 Log::msg (Log::Warning, " %s: gf_isom_set_track_enabled" , gf_error_to_string (e));
600585 throw std::runtime_error (" [GPACMuxMP4] Cannot enable track" );
601586 }
602587
588+ const uint8_t *extradata;
589+ size_t extradataSize;
590+ metadata->getExtradata (extradata, extradataSize);
591+
603592 u32 di;
604- e = gf_isom_avc_config_new (m_iso, trackNum, avccfg, nullptr , nullptr , &di);
605- if (e != GF_OK) {
606- Log::msg (Log::Warning, " %s: gf_isom_avc_config_new" , gf_error_to_string (e));
607- throw std::runtime_error (" [GPACMuxMP4] Cannot create AVC config" );
593+ if (metadata->getAVCodecContext ()->codec_id == CODEC_ID_H264) {
594+ GF_AVCConfig *avccfg = gf_odf_avc_cfg_new ();
595+ if (!avccfg) {
596+ Log::msg (Log::Warning, " Cannot create AVCConfig" );
597+ throw std::runtime_error (" [GPACMuxMP4] Container format import failed (AVC)" );
598+ }
599+ e = avc_import_ffextradata (extradata, extradataSize, avccfg);
600+ if (e == GF_OK) {
601+ e = gf_isom_avc_config_new (m_iso, trackNum, avccfg, nullptr , nullptr , &di);
602+ if (e != GF_OK) {
603+ Log::msg (Log::Warning, " %s: gf_isom_avc_config_new" , gf_error_to_string (e));
604+ throw std::runtime_error (" [GPACMuxMP4] Cannot create AVC config" );
605+ }
606+ gf_odf_avc_cfg_del (avccfg);
607+ }
608+ } else if (metadata->getAVCodecContext ()->codec_id == AV_CODEC_ID_H265) {
609+ GF_HEVCConfig *hevccfg = gf_odf_hevc_cfg_new ();
610+ if (!hevccfg) {
611+ Log::msg (Log::Warning, " Cannot create HEVCConfig" );
612+ throw std::runtime_error (" [GPACMuxMP4] Container format import failed (HEVC)" );
613+ }
614+ e = hevc_import_ffextradata (extradata, extradataSize, hevccfg);
615+ if (e == GF_OK) {
616+ e = gf_isom_hevc_config_new (m_iso, trackNum, hevccfg, nullptr , nullptr , &di);
617+ if (e != GF_OK) {
618+ Log::msg (Log::Warning, " %s: gf_isom_avc_config_new" , gf_error_to_string (e));
619+ throw std::runtime_error (" [GPACMuxMP4] Cannot create AVC config" );
620+ }
621+ gf_odf_hevc_cfg_del (hevccfg);
622+ }
623+ } else {
624+ throw std::runtime_error (" [GPACMuxMP4] Unknown codec" );
625+ }
626+ if (e) {
627+ if (e == GF_NON_COMPLIANT_BITSTREAM) {
628+ /* non Annex B: assume this is AVCC*/
629+ GF_ESD *esd = (GF_ESD *)gf_odf_desc_esd_new (0 );
630+ esd->ESID = 1 ; /* FIXME: only one track: set trackID?*/
631+ esd->decoderConfig ->streamType = GF_STREAM_VISUAL;
632+ esd->decoderConfig ->avgBitrate = esd->decoderConfig ->maxBitrate = 0 ;
633+ esd->decoderConfig ->objectTypeIndication = metadata->getAVCodecContext ()->codec_id == CODEC_ID_H264 ? GPAC_OTI_VIDEO_AVC : GPAC_OTI_VIDEO_HEVC;
634+ esd->decoderConfig ->decoderSpecificInfo ->dataLength = (u32 )extradataSize;
635+ esd->decoderConfig ->decoderSpecificInfo ->data = (char *)gf_malloc (extradataSize);
636+ memcpy (esd->decoderConfig ->decoderSpecificInfo ->data , extradata, extradataSize);
637+ esd->slConfig ->predefined = SLPredef_MP4;
638+
639+ e = gf_isom_new_mpeg4_description (m_iso, trackNum, esd, nullptr , nullptr , &di);
640+ if (e != GF_OK) {
641+ Log::msg (Log::Warning, " %s: gf_isom_new_mpeg4_description" , gf_error_to_string (e));
642+ throw std::runtime_error (" [GPACMuxMP4] Cannot create MPEG-4 config" );
643+ }
644+ gf_odf_desc_del ((GF_Descriptor*)esd);
645+ isAnnexB = false ;
646+ } else {
647+ throw std::runtime_error (" [GPACMuxMP4] Container format import failed" );
648+ }
608649 }
609-
610- gf_odf_avc_cfg_del (avccfg);
611650
612651 auto const res = metadata->getResolution ();
613652 gf_isom_set_visual_info (m_iso, trackNum, di, res.width , res.height );
@@ -752,7 +791,13 @@ void GPACMuxMP4::process() {
752791
753792 u32 mediaType = gf_isom_get_media_type (m_iso, 1 );
754793 if (mediaType == GF_ISOM_MEDIA_VISUAL) {
755- fillVideoSampleData (bufPtr, bufLen, sample);
794+ if (isAnnexB) {
795+ fillVideoSampleData (bufPtr, bufLen, sample);
796+ } else {
797+ sample.data = (char *)bufPtr;
798+ sample.dataLength = bufLen;
799+ sample.setDataOwnership (false );
800+ }
756801 } else if (mediaType == GF_ISOM_MEDIA_AUDIO) {
757802 sample.data = (char *)bufPtr;
758803 sample.dataLength = bufLen;
0 commit comments