static int set_param( hnd_t handle, x264_param_t *p_param ) { mp4_hnd_t *p_mp4 = handle; p_mp4->i_delay_frames = p_param->i_bframe ? (p_param->i_bframe_pyramid ? 2 : 1) : 0; p_mp4->i_dts_compress_multiplier = p_mp4->b_dts_compress * p_mp4->i_delay_frames + 1; p_mp4->i_time_res = (uint64_t)p_param->i_timebase_den * p_mp4->i_dts_compress_multiplier; p_mp4->i_time_inc = (uint64_t)p_param->i_timebase_num * p_mp4->i_dts_compress_multiplier; FAIL_IF_ERR( p_mp4->i_time_res > UINT32_MAX, "mp4", "MP4 media timescale %"PRIu64" exceeds maximum\n", p_mp4->i_time_res ) p_mp4->i_track = gf_isom_new_track( p_mp4->p_file, 0, GF_ISOM_MEDIA_VISUAL, p_mp4->i_time_res ); p_mp4->p_config = gf_odf_avc_cfg_new(); gf_isom_avc_config_new( p_mp4->p_file, p_mp4->i_track, p_mp4->p_config, NULL, NULL, &p_mp4->i_descidx ); gf_isom_set_track_enabled( p_mp4->p_file, p_mp4->i_track, 1 ); gf_isom_set_visual_info( p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx, p_param->i_width, p_param->i_height ); if( p_param->vui.i_sar_width && p_param->vui.i_sar_height ) { uint64_t dw = p_param->i_width << 16; uint64_t dh = p_param->i_height << 16; double sar = (double)p_param->vui.i_sar_width / p_param->vui.i_sar_height; if( sar > 1.0 ) dw *= sar ; else dh /= sar; gf_isom_set_pixel_aspect_ratio( p_mp4->p_file, p_mp4->i_track, p_mp4->i_descidx, p_param->vui.i_sar_width, p_param->vui.i_sar_height ); gf_isom_set_track_layout_info( p_mp4->p_file, p_mp4->i_track, dw, dh, 0, 0, 0 ); } p_mp4->i_data_size = p_param->i_width * p_param->i_height * 3 / 2; p_mp4->p_sample->data = malloc( p_mp4->i_data_size ); if( !p_mp4->p_sample->data ) { p_mp4->i_data_size = 0; return -1; } return 0; }
//sps,pps第一个字节为0x67或68, bool EasyMP4Writer::WriteH264SPSandPPS(unsigned char*sps,int spslen,unsigned char*pps,int ppslen,int width,int height) { p_videosample=gf_isom_sample_new(); p_videosample->data=(char*)malloc(1024*1024); p_config=gf_odf_avc_cfg_new(); gf_isom_avc_config_new(p_file,m_videtrackid,p_config,NULL,NULL,&i_videodescidx); gf_isom_set_visual_info(p_file,m_videtrackid,i_videodescidx,width,height); GF_AVCConfigSlot m_slotsps={0}; GF_AVCConfigSlot m_slotpps={0}; p_config->configurationVersion = 1; p_config->AVCProfileIndication = sps[1]; p_config->profile_compatibility = sps[2]; p_config->AVCLevelIndication = sps[3]; m_slotsps.size=spslen; m_slotsps.data=(char*)malloc(spslen); memcpy(m_slotsps.data,sps,spslen); gf_list_add(p_config->sequenceParameterSets,&m_slotsps); m_slotpps.size=ppslen; m_slotpps.data=(char*)malloc(ppslen); memcpy(m_slotpps.data,pps,ppslen); gf_list_add(p_config->pictureParameterSets,&m_slotpps); gf_isom_avc_config_update(p_file,m_videtrackid,1,p_config); free(m_slotsps.data); free(m_slotpps.data); return true; }
int dc_gpac_video_moov_create(VideoOutputFile *video_output_file, char *filename) { GF_Err ret; AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; u32 di, track; //TODO: For the moment it is fixed //u32 sample_dur = video_output_file->codec_ctx->time_base.den; //int64_t profile = 0; //av_opt_get_int(video_output_file->codec_ctx->priv_data, "level", AV_OPT_SEARCH_CHILDREN, &profile); video_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); if (!video_output_file->isof) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); return -1; } //gf_isom_store_movie_config(video_output_file->isof, 0); track = gf_isom_new_track(video_output_file->isof, 0, GF_ISOM_MEDIA_VISUAL, video_codec_ctx->time_base.den); video_output_file->trackID = gf_isom_get_track_id(video_output_file->isof, track); video_output_file->timescale = video_codec_ctx->time_base.den; if (!video_output_file->frame_dur) video_output_file->frame_dur = video_codec_ctx->time_base.num; if (!track) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); return -1; } ret = gf_isom_set_track_enabled(video_output_file->isof, track, 1); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret))); return -1; } ret = dc_gpac_video_write_config(video_output_file, &di, track); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: dc_gpac_video_write_config\n", gf_error_to_string(ret))); return -1; } gf_isom_set_visual_info(video_output_file->isof, track, di, video_codec_ctx->width, video_codec_ctx->height); gf_isom_set_sync_table(video_output_file->isof, track); ret = gf_isom_setup_track_fragment(video_output_file->isof, track, 1, video_output_file->use_source_timing ? (u32) video_output_file->frame_dur : 1, 0, 0, 0, 0); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret))); return -1; } //gf_isom_add_track_to_root_od(video_output_file->isof,1); ret = gf_isom_finalize_for_fragment(video_output_file->isof, track); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); return -1; } ret = gf_media_get_rfc_6381_codec_name(video_output_file->isof, track, video_output_file->video_data_conf->codec6381); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); return -1; } return 0; }