bool EasyMP4Writer::CreateMP4File(char*filename,int flag) { SaveFile(); m_audiostartimestamp=-1; m_videostartimestamp=-1; if(filename==NULL) { char filename2[256]={0}; sprintf_s(filename2,"%d-gpac%d.mp4",time(NULL),rand()); p_file=gf_isom_open(filename2,GF_ISOM_OPEN_WRITE,NULL);//打开文件 }else p_file=gf_isom_open(filename,GF_ISOM_OPEN_WRITE,NULL);//打开文件 if (p_file==NULL) { return false; } gf_isom_set_brand_info(p_file,GF_ISOM_BRAND_MP42,0); if(flag&ZOUTFILE_FLAG_VIDEO) { m_videtrackid=gf_isom_new_track(p_file,0,GF_ISOM_MEDIA_VISUAL,1000); gf_isom_set_track_enabled(p_file,m_videtrackid,1); } if(flag&ZOUTFILE_FLAG_AUDIO) { m_audiotrackid=gf_isom_new_track(p_file,0,GF_ISOM_MEDIA_AUDIO,1000); gf_isom_set_track_enabled(p_file,m_audiotrackid,1); } return true; }
void V4SceneManager::SaveFile(const char *path) { GF_SMEncodeOptions opts; char rad_name[5000]; /* First dump the scene in a BT file */ strcpy(rad_name, "dump"); m_pSm->scene_graph->RootNode = NULL; gf_sm_dump(m_pSm, rad_name, 0); /* Then reload properly (overriding the current SceneManager)*/ GF_SceneLoader load; memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = "dump.bt"; load.ctx = m_pSm; gf_sm_load_init(&load); gf_sm_load_run(&load); gf_sm_load_done(&load); /* Finally encode the file */ GF_ISOFile *mp4 = gf_isom_open(path, GF_ISOM_WRITE_EDIT, NULL); m_pSm->max_node_id = gf_sg_get_max_node_id(m_pSm->scene_graph); memset(&opts, 0, sizeof(opts)); opts.flags = GF_SM_LOAD_MPEG4_STRICT; gf_sm_encode_to_file(m_pSm, mp4, &opts); gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1); gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1); gf_isom_close(mp4); }
GF_EXPORT GF_Err gf_beng_save_context(GF_BifsEngine *codec, char * ctxFileName) { u32 d_mode, do_enc; char szF[GF_MAX_PATH], *ext; GF_Err e; /*check if we dump to BT, XMT or encode to MP4*/ strcpy(szF, ctxFileName); ext = strrchr(szF, '.'); d_mode = GF_SM_DUMP_BT; do_enc = 0; if (ext) { if (!stricmp(ext, ".xmt") || !stricmp(ext, ".xmta")) d_mode = GF_SM_DUMP_XMTA; else if (!stricmp(ext, ".mp4")) do_enc = 1; ext[0] = 0; } if (do_enc) { GF_ISOFile *mp4; strcat(szF, ".mp4"); mp4 = gf_isom_open(szF, GF_ISOM_OPEN_WRITE, NULL); e = gf_sm_encode_to_file(codec->ctx, mp4, NULL); if (e) gf_isom_delete(mp4); else gf_isom_close(mp4); } else { e = gf_sm_dump(codec->ctx, szF, d_mode); } return e; }
static GF_Err ISOW_Open(GF_StreamingCache *mc, GF_ClientService *serv, const char *location_and_name, Bool keep_existing_files) { char szRoot[GF_MAX_PATH], szPath[GF_MAX_PATH], *ext; ISOMReader *cache = (ISOMReader *)mc->priv; if (cache->mov || cache->service) return GF_BAD_PARAM; strcpy(szRoot, location_and_name); ext = strrchr(szRoot, '.'); if (ext) ext[0] = 0; strcpy(szPath, szRoot); strcat(szPath, ".mp4"); if (keep_existing_files) { FILE *f = gf_fopen(szPath, "rb"); if (f) { u32 i=0; gf_fclose(f); while (1) { sprintf(szPath, "%s_%04d.mp4", szRoot, i); f = gf_fopen(szPath, "rb"); if (!f) break; gf_fclose(f); i++; } } } /*create a new movie in write mode (eg no editing)*/ cache->mov = gf_isom_open(szPath, GF_ISOM_OPEN_WRITE, NULL); if (!cache->mov) return gf_isom_last_error(NULL); cache->service = serv; return GF_OK; }
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt ) { mp4_hnd_t *p_mp4; *p_handle = NULL; FILE *fh = fopen( psz_filename, "w" ); if( !fh ) return -1; FAIL_IF_ERR( !x264_is_regular_file( fh ), "mp4", "MP4 output is incompatible with non-regular file `%s'\n", psz_filename ) fclose( fh ); if( !(p_mp4 = malloc( sizeof(mp4_hnd_t) )) ) return -1; memset( p_mp4, 0, sizeof(mp4_hnd_t) ); p_mp4->p_file = gf_isom_open( psz_filename, GF_ISOM_OPEN_WRITE, NULL ); p_mp4->b_dts_compress = opt->use_dts_compress; if( !(p_mp4->p_sample = gf_isom_sample_new()) ) { close_file( p_mp4, 0, 0 ); return -1; } gf_isom_set_brand_info( p_mp4->p_file, GF_ISOM_BRAND_AVC1, 0 ); *p_handle = p_mp4; return 0; }
void V4SceneGraph::SaveFile(const char *path) { char rad_name[5000]; strcpy(rad_name, "dump"); gf_sm_dump(m_pSm, rad_name, 0); GF_ISOFile *mp4 = gf_isom_open(path, GF_ISOM_WRITE_EDIT, NULL); m_pSm->max_node_id = gf_sg_get_max_node_id(m_pSm->scene_graph); gf_sm_encode_to_file(m_pSm, mp4, "c:\\log.txt", NULL, GF_SM_LOAD_MPEG4_STRICT, 0); gf_isom_close(mp4); }
GF_Err create_laser_mp4(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *size) { char mp4_path[100], *ext; GF_Err e = GF_OK; GF_ISOFile *mp4; *size = 0; strcpy(mp4_path, item_name); ext = strrchr(mp4_path, '.'); strcpy(ext, ".mp4"); mp4 = gf_isom_open(mp4_path, GF_ISOM_WRITE_EDIT, NULL); if (!mp4) { if (lc->verbose) fprintf(stdout, "Could not open file %s for writing\n", mp4_path); e = GF_IO_ERR; } else { GF_SMEncodeOptions opts; memset(&opts, 0, sizeof(GF_SMEncodeOptions)); opts.auto_qant = 1; opts.resolution = 8; e = encode_laser(lc, item_path, mp4, &opts); if (e) { if (lc->verbose) fprintf(stdout, "Could not encode MP4 file from %s\n", item_path); gf_isom_delete(mp4); } else { gf_isom_close(mp4); mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL); if (!mp4) { if (lc->verbose) fprintf(stdout, "Could not open file %s for reading\n", mp4_path); e = GF_IO_ERR; } else { e = get_laser_track_size(mp4, size); if (e) { if (lc->verbose) fprintf(stdout, "Could not get MP4 file size\n"); } gf_isom_close(mp4); } } } return e; }
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt ) { mp4_hnd_t *p_mp4; *p_handle = NULL; FILE *fh = x264_fopen( psz_filename, "w" ); if( !fh ) return -1; FAIL_IF_ERR( !x264_is_regular_file( fh ), "mp4", "MP4 output is incompatible with non-regular file `%s'\n", psz_filename ) fclose( fh ); if( !(p_mp4 = malloc( sizeof(mp4_hnd_t) )) ) return -1; memset( p_mp4, 0, sizeof(mp4_hnd_t) ); #ifdef _WIN32 /* GPAC doesn't support Unicode filenames. */ char ansi_filename[MAX_PATH]; FAIL_IF_ERR( !x264_ansi_filename( psz_filename, ansi_filename, MAX_PATH, 1 ), "mp4", "invalid ansi filename\n" ) p_mp4->p_file = gf_isom_open( ansi_filename, GF_ISOM_OPEN_WRITE, NULL ); #else p_mp4->p_file = gf_isom_open( psz_filename, GF_ISOM_OPEN_WRITE, NULL ); #endif p_mp4->b_dts_compress = opt->use_dts_compress; if( !(p_mp4->p_sample = gf_isom_sample_new()) ) { close_file( p_mp4, 0, 0 ); return -1; } gf_isom_set_brand_info( p_mp4->p_file, GF_ISOM_BRAND_AVC1, 0 ); *p_handle = p_mp4; return 0; }
void V4SceneManager::LoadFile(const char *path) { LoadCommon(); GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal(); /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ GF_SceneLoader load; memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = path; load.ctx = m_pSm; if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL); gf_sm_load_init(&load); gf_sm_load_run(&load); gf_sm_load_done(&load); if (load.isom) gf_isom_delete(load.isom); /* SceneManager should be initialized and filled correctly */ gf_sg_set_scene_size_info(m_pIs->graph, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics); // TODO : replace with GetBifsStream GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); if (sc->streamType == 3) { GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); //gf_sg_command_apply(m_pIs->graph, c, 0); /* This is a patch to solve the save pb: When ApplyCommand is made on a Scene Replace Command The command node is set to NULL When we save a BIFS stream whose first command is of this kind, the file saver thinks the bifs commands should come from an NHNT file This is a temporary patch */ if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pIs->graph->RootNode; } } gf_sc_set_scene(term->compositor, m_pIs->graph); m_pIs->graph_attached = 1; // TODO : read actual values from file SetLength(50); SetFrameRate(25); // retrieves all the node from the tree and adds them to the node pool GF_Node * root = gf_sg_get_root_node(m_pIs->graph); // CreateDictionnary(); }
GF_Err decode_svg(GF_LoadCompare *lc, char *item_name, char *item_path, char *svg_out_path) { GF_SceneManager *ctx; GF_SceneGraph *sg; GF_SceneLoader load; GF_ISOFile *mp4; GF_Err e = GF_OK; char mp4_path[256]; char *ext; strcpy(mp4_path, item_name); ext = strrchr(mp4_path, '.'); strcpy(ext, ".mp4"); mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL); if (!mp4) { if (lc->verbose) fprintf(stdout, "Could not open file %s\n", mp4_path); e = GF_IO_ERR; } else { sg = gf_sg_new(); ctx = gf_sm_new(sg); memset(&load, 0, sizeof(GF_SceneLoader)); load.isom = mp4; load.ctx = ctx; e = gf_sm_load_init(&load); if (e) { fprintf(stderr, "Error loading MP4 file\n"); } else { e = gf_sm_load_run(&load); if (e) { fprintf(stderr, "Error loading MP4 file\n"); } else { gf_sm_load_done(&load); ext = strrchr(svg_out_path, '.'); ext[0] = 0; e = gf_sm_dump(ctx, svg_out_path, GF_SM_DUMP_SVG); if (e) { fprintf(stderr, "Error dumping SVG from MP4 file\n"); } } } gf_sm_del(ctx); gf_sg_del(sg); gf_isom_close(mp4); } return e; }
GF_EXPORT GF_Err gf_seng_save_context(GF_SceneEngine *seng, char *ctxFileName) { #ifdef GPAC_DISABLE_SCENE_DUMP return GF_NOT_SUPPORTED; #else u32 d_mode, do_enc; char szF[GF_MAX_PATH], *ext; GF_Err e; /*check if we dump to BT, XMT or encode to MP4*/ ext = NULL; if (ctxFileName) { strcpy(szF, ctxFileName); ext = strrchr(szF, '.'); } d_mode = GF_SM_DUMP_BT; do_enc = 0; if (ext) { if (!stricmp(ext, ".xmt") || !stricmp(ext, ".xmta")) d_mode = GF_SM_DUMP_XMTA; else if (!stricmp(ext, ".mp4")) do_enc = 1; ext[0] = 0; } if (do_enc) { #ifndef GPAC_DISABLE_SCENE_ENCODER GF_ISOFile *mp4; strcat(szF, ".mp4"); mp4 = gf_isom_open(szF, GF_ISOM_OPEN_WRITE, NULL); e = gf_sm_encode_to_file(seng->ctx, mp4, NULL); if (e) gf_isom_delete(mp4); else gf_isom_close(mp4); #else return GF_NOT_SUPPORTED; #endif } else { e = gf_sm_dump(seng->ctx, ctxFileName ? szF : NULL, d_mode); } return e; #endif }
GF_Err TTIn_LoadFile(GF_InputService *plug, const char *url, Bool is_cache) { GF_Err e; GF_MediaImporter import; char szFILE[GF_MAX_PATH]; TTIn *tti = (TTIn *)plug->priv; const char *cache_dir; if (!tti || !url) return GF_BAD_PARAM; cache_dir = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory"); if (cache_dir && strlen(cache_dir)) { if (cache_dir[strlen(cache_dir)-1] != GF_PATH_SEPARATOR) { sprintf(szFILE, "%s%csrt_%p_mp4", cache_dir, GF_PATH_SEPARATOR, tti); } else { sprintf(szFILE, "%ssrt_%p_mp4", cache_dir, tti); } } else { sprintf(szFILE, "%p_temp_mp4", tti); } tti->mp4 = gf_isom_open(szFILE, GF_ISOM_OPEN_WRITE, NULL); if (!tti->mp4) return gf_isom_last_error(NULL); if (tti->szFile) gf_free(tti->szFile); tti->szFile = gf_strdup(szFILE); memset(&import, 0, sizeof(GF_MediaImporter)); import.dest = tti->mp4; /*override layout from sub file*/ import.flags = GF_IMPORT_SKIP_TXT_BOX; import.in_name = gf_strdup(url); e = gf_media_import(&import); if (!e) { tti->tt_track = 1; gf_isom_text_set_streaming_mode(tti->mp4, 1); } if (import.in_name) gf_free(import.in_name); return e; }
GF_Err get_mp4_loadtime(GF_LoadCompare *lc, char *item_name, char *item_path, u32 *loadtime) { char mp4_path[100], *ext; GF_Err e = GF_OK; GF_ISOFile *mp4; *loadtime = 0; strcpy(mp4_path, item_name); ext = strrchr(mp4_path, '.'); strcpy(ext, ".mp4"); mp4 = gf_isom_open(mp4_path, GF_ISOM_OPEN_READ, NULL); if (!mp4) { if (lc->verbose) fprintf(stdout, "Could not open file %s for reading\n", mp4_path); e = GF_IO_ERR; } else { e = load_mp4(lc, mp4, loadtime); if (e) { if (lc->verbose) fprintf(stdout, "Could not get MP4 file load time\n"); } } gf_isom_close(mp4); return e; }
/*import cubic QTVR to mp4*/ GF_Err gf_sm_load_init_qt(GF_SceneLoader *load) { u32 i, di, w, h, tk, nb_samp; Bool has_qtvr; GF_ISOSample *samp; GF_ISOFile *src; GF_StreamContext *st; GF_AUContext *au; GF_Command *com; M_Background *back; M_NavigationInfo *ni; M_Group *gr; GF_ODUpdate *odU; GF_SceneGraph *sg; GF_ObjectDescriptor *od; GF_ESD *esd; if (!load->ctx) return GF_NOT_SUPPORTED; src = gf_isom_open(load->fileName, GF_ISOM_OPEN_READ, NULL); if (!src) return gf_qt_report(load, GF_URL_ERROR, "Opening file %s failed", load->fileName); w = h = tk = 0; nb_samp = 0; has_qtvr = 0; for (i=0; i<gf_isom_get_track_count(src); i++) { switch (gf_isom_get_media_type(src, i+1)) { case GF_ISOM_MEDIA_VISUAL: if (gf_isom_get_media_subtype(src, i+1, 1) == GF_4CC('j', 'p', 'e', 'g')) { GF_GenericSampleDescription *udesc = gf_isom_get_generic_sample_description(src, i+1, 1); if ((udesc->width>w) || (udesc->height>h)) { w = udesc->width; h = udesc->height; tk = i+1; nb_samp = gf_isom_get_sample_count(src, i+1); } if (udesc->extension_buf) gf_free(udesc->extension_buf); gf_free(udesc); } break; case GF_4CC('q','t','v','r'): has_qtvr = 1; break; } } if (!has_qtvr) { gf_isom_delete(src); return gf_qt_report(load, GF_NOT_SUPPORTED, "QTVR not found - no conversion available for this QuickTime movie"); } if (!tk) { gf_isom_delete(src); return gf_qt_report(load, GF_NON_COMPLIANT_BITSTREAM, "No associated visual track with QTVR movie"); } if (nb_samp!=6) { gf_isom_delete(src); return gf_qt_report(load, GF_NOT_SUPPORTED, "Movie %s doesn't look a Cubic QTVR - sorry...", load->fileName); } GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("QT: Importing Cubic QTVR Movie")); /*create scene*/ sg = load->ctx->scene_graph; gr = (M_Group *) gf_node_new(sg, TAG_MPEG4_Group); gf_node_register((GF_Node *)gr, NULL); st = gf_sm_stream_new(load->ctx, 1, GF_STREAM_SCENE, 1); au = gf_sm_stream_au_new(st, 0, 0, 1); com = gf_sg_command_new(load->ctx->scene_graph, GF_SG_SCENE_REPLACE); gf_list_add(au->commands, com); com->node = (GF_Node *)gr; back = (M_Background *) gf_node_new(sg, TAG_MPEG4_Background); gf_node_list_add_child( &gr->children, (GF_Node*)back); gf_node_register((GF_Node *)back, (GF_Node *)gr); gf_sg_vrml_mf_alloc(&back->leftUrl, GF_SG_VRML_MFURL, 1); back->leftUrl.vals[0].OD_ID = 2; gf_sg_vrml_mf_alloc(&back->frontUrl, GF_SG_VRML_MFURL, 1); back->frontUrl.vals[0].OD_ID = 3; gf_sg_vrml_mf_alloc(&back->rightUrl, GF_SG_VRML_MFURL, 1); back->rightUrl.vals[0].OD_ID = 4; gf_sg_vrml_mf_alloc(&back->backUrl, GF_SG_VRML_MFURL, 1); back->backUrl.vals[0].OD_ID = 5; gf_sg_vrml_mf_alloc(&back->topUrl, GF_SG_VRML_MFURL, 1); back->topUrl.vals[0].OD_ID = 6; gf_sg_vrml_mf_alloc(&back->bottomUrl, GF_SG_VRML_MFURL, 1); back->bottomUrl.vals[0].OD_ID = 7; ni = (M_NavigationInfo *) gf_node_new(sg, TAG_MPEG4_NavigationInfo); gf_node_list_add_child(&gr->children, (GF_Node*)ni); gf_node_register((GF_Node *)ni, (GF_Node *)gr); gf_sg_vrml_mf_reset(&ni->type, GF_SG_VRML_MFSTRING); gf_sg_vrml_mf_alloc(&ni->type, GF_SG_VRML_MFSTRING, 1); ni->type.vals[0] = gf_strdup("QTVR"); /*create ODs*/ st = gf_sm_stream_new(load->ctx, 2, GF_STREAM_OD, 1); au = gf_sm_stream_au_new(st, 0, 0, 1); odU = (GF_ODUpdate*) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); gf_list_add(au->commands, odU); for (i=0; i<6; i++) { GF_MuxInfo *mi; FILE *img; char szName[1024]; od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); od->objectDescriptorID = 2+i; esd = gf_odf_desc_esd_new(2); esd->decoderConfig->streamType = GF_STREAM_VISUAL; esd->decoderConfig->objectTypeIndication = GPAC_OTI_IMAGE_JPEG; esd->ESID = 3+i; /*extract image and remember it*/ mi = (GF_MuxInfo *) gf_odf_desc_new(GF_ODF_MUXINFO_TAG); gf_list_add(esd->extensionDescriptors, mi); mi->delete_file = 1; sprintf(szName, "%s_img%d.jpg", load->fileName, esd->ESID); mi->file_name = gf_strdup(szName); gf_list_add(od->ESDescriptors, esd); gf_list_add(odU->objectDescriptors, od); samp = gf_isom_get_sample(src, tk, i+1, &di); img = gf_f64_open(mi->file_name, "wb"); fwrite(samp->data, samp->dataLength, 1, img); fclose(img); gf_isom_sample_del(&samp); } gf_isom_delete(src); return GF_OK; }
void isor_net_io(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; u32 size = 0; char *local_name; ISOMReader *read = (ISOMReader *) cbk; /*handle service message*/ if (!read->buffering) gf_service_download_update_stats(read->dnload); if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { e = GF_EOS; } else if (param->msg_type==GF_NETIO_DATA_EXCHANGE) { e = GF_OK; size = param->size; } else { e = param->error; } if (e<GF_OK) { /*error opening service*/ if (!read->mov) { /* if there is an intermediate between this module and the terminal, report to it */ if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, e, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, e); } } return; } /*open file if not done yet (bad interleaving)*/ if (e==GF_EOS) { const char *local_name; if (read->mov) return; local_name = gf_dm_sess_get_cache_name(read->dnload); if (!local_name) { if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, GF_SERVICE_ERROR, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, GF_SERVICE_ERROR); } return; } e = GF_OK; read->mov = gf_isom_open(local_name, GF_ISOM_OPEN_READ, NULL); if (!read->mov) e = gf_isom_last_error(NULL); else read->time_scale = gf_isom_get_timescale(read->mov); read->frag_type = gf_isom_is_fragmented(read->mov) ? 1 : 0; if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, GF_OK, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, GF_OK); } if (read->no_service_desc) isor_declare_objects(read); } if (!size) return; /*service is opened, nothing to do*/ if (read->mov) { isor_check_buffer_level(read); /*end of chunk*/ if (read->frag_type && (param->reply==1) ) { u64 bytesMissing = 0; gf_mx_p(read->segment_mutex); e = gf_isom_refresh_fragmented(read->mov, &bytesMissing, NULL); gf_mx_v(read->segment_mutex); } return; } /*try to open the service*/ local_name = (char *)gf_dm_sess_get_cache_name(read->dnload); if (!local_name) { if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, GF_SERVICE_ERROR, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, GF_SERVICE_ERROR); } return; } /*not enogh data yet*/ if (read->missing_bytes && (read->missing_bytes > size) ) { read->missing_bytes -= size; return; } e = gf_isom_open_progressive(local_name, 0, 0, &read->mov, &read->missing_bytes); switch (e) { case GF_ISOM_INCOMPLETE_FILE: return; case GF_OK: break; default: if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, e, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, e); } return; } read->frag_type = gf_isom_is_fragmented(read->mov) ? 1 : 0; /*ok let's go, we can setup the decoders */ read->time_scale = gf_isom_get_timescale(read->mov); if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_FALSE, GF_FALSE, GF_OK, NULL, NULL); } else { gf_service_connect_ack(read->service, NULL, GF_OK); } if (read->no_service_desc) isor_declare_objects(read); }
int main(int argc, char **argv) { /********************/ /* declarations */ /********************/ char *input, *output, tmpstr[GF_MAX_PATH]; GF_ISOFile *isom_file_in; GF_MediaImporter import; AdobeHDSCtx ctx; GF_Err e; u32 i; /*****************/ /* gpac init */ /*****************/ gf_sys_init(GF_MemTrackerNone); gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING); /***********************/ /* initialisations */ /***********************/ input = NULL; output = NULL; isom_file_in = NULL; memset(&import, 0, sizeof(GF_MediaImporter)); e = GF_OK; memset(&ctx, 0, sizeof(ctx)); ctx.curr_time = 0; ctx.segnum = 1; /*********************************************/ /* parse arguments and build HDS context */ /*********************************************/ if (GF_OK != parse_args(argc, argv, &input, &output, &ctx.curr_time, &ctx.segnum)) { usage(argv[0]); goto exit; } ctx.multirate_manifest = adobe_alloc_multirate_manifest(output); #if 0 /*'moov' conversion tests*/ { char metamoov64[GF_MAX_PATH]; u32 metamoov64_len; unsigned char metamoov[GF_MAX_PATH]; u32 metamoov_len=GF_MAX_PATH; FILE *f = gf_fopen("metamoov64"/*input*/, "rt"); gf_fseek(f, 0, SEEK_END); metamoov64_len = (u32)gf_ftell(f); gf_fseek(f, 0, SEEK_SET); fread(metamoov64, metamoov64_len, 1, f); metamoov_len = gf_base64_decode(metamoov64, metamoov64_len, metamoov, metamoov_len); gf_fclose(f); f = gf_fopen("metamoov", "wb"); fwrite(metamoov, metamoov_len, 1, f); gf_fclose(f); return 0; } #endif #if 0 /*'abst'conversion tests*/ { char bootstrap64[GF_MAX_PATH]; u32 bootstrap64_len; unsigned char bootstrap[GF_MAX_PATH]; u32 bootstrap_len=GF_MAX_PATH; GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox *)abst_New(); GF_BitStream *bs; #if 1 //64 FILE *f = gf_fopen("bootstrap64"/*input*/, "rt"); gf_fseek(f, 0, SEEK_END); bootstrap64_len = (u32)gf_ftell(f); gf_fseek(f, 0, SEEK_SET); fread(bootstrap64, bootstrap64_len, 1, f); bootstrap_len = gf_base64_decode(bootstrap64, bootstrap64_len, bootstrap, bootstrap_len); #else //binary bootstrap FILE *f = gf_fopen("bootstrap.bin"/*input*/, "rb"); gf_fseek(f, 0, SEEK_END); bootstrap_len = (u32)gf_ftell(f); gf_fseek(f, 0, SEEK_SET); fread(bootstrap, bootstrap_len, 1, f); #endif bs = gf_bs_new(bootstrap+8, bootstrap_len-8, GF_BITSTREAM_READ); abst->size = bootstrap[2]*256+bootstrap[3]; assert(abst->size<GF_MAX_PATH); abst_Read((GF_Box*)abst, bs); gf_bs_del(bs); //then rewrite with just one 'afrt' memset(bootstrap, 0, bootstrap_len); bs = gf_bs_new(bootstrap, bootstrap_len, GF_BITSTREAM_WRITE); abst_Write((GF_Box*)abst, bs); bootstrap_len = (u32)gf_bs_get_position(bs); gf_bs_del(bs); gf_fclose(f); f = gf_fopen("bootstrap", "wt"); bootstrap64_len = gf_base64_encode(bootstrap, bootstrap_len, bootstrap64, GF_MAX_PATH); fwrite(bootstrap64, bootstrap64_len, 1, f); fprintf(f, "\n\n"); abst_dump((GF_Box*)abst, f); gf_fclose(f); abst_del((GF_Box*)abst); return 0; } #endif /*****************/ /* main loop */ /*****************/ import.trackID = 0; import.in_name = input; import.flags = GF_IMPORT_PROBE_ONLY; //create output or open when recovering from a saved state sprintf(tmpstr, "%s_import.mp4", input); isom_file_in = gf_isom_open(tmpstr, GF_ISOM_WRITE_EDIT, NULL); if (!isom_file_in) { fprintf(stderr, "Error opening output file %s: %s\n", tmpstr, gf_error_to_string(e)); assert(0); goto exit; } import.dest = isom_file_in; //probe input e = gf_media_import(&import); if (e) { fprintf(stderr, "Error while importing input file %s: %s\n", input, gf_error_to_string(e)); assert(0); goto exit; } //import input data import.flags = 0; for (i=0; i<import.nb_tracks; i++) { import.trackID = import.tk_info[i].track_num; e = gf_media_import(&import); if (e) { fprintf(stderr, "Error while importing track number %u, input file %s: %s\n", import.trackID, input, gf_error_to_string(e)); assert(0); goto exit; } } //Adobe specific stuff e = adobize_segment(isom_file_in, &ctx); if (e) { fprintf(stderr, "Couldn't turn the ISOM fragmented file into an Adobe f4v segment: %s\n", gf_error_to_string(e)); assert(0); goto exit; } //interleave data and remove imported file //FIXME: set multiple fragments: sprintf(tmpstr, "%s_HD_100_Seg%u-Frag1", output, ctx.segnum); //FIXME: "HD", "100" and fragnum: pass as arg //e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0); e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0+gf_isom_get_duration(isom_file_in)/gf_isom_get_timescale(isom_file_in)); if (e) { fprintf(stderr, "Error while fragmenting file to output %s: %s\n", output, gf_error_to_string(e)); assert(0); goto exit; } gf_isom_delete(isom_file_in); isom_file_in = NULL; e = adobe_gen_multirate_manifest(ctx.multirate_manifest, ctx.bootstrap, ctx.bootstrap_size); if (e) { fprintf(stderr, "Couldn't generate Adobe f4m manifest: %s\n", gf_error_to_string(e)); assert(0); goto exit; } exit: //delete intermediate mp4 file if (isom_file_in) gf_isom_delete(isom_file_in); if (ctx.multirate_manifest) adobe_free_multirate_manifest(ctx.multirate_manifest); if (ctx.bootstrap) { gf_free(ctx.bootstrap); //ctx.bootstrap = NULL; //ctx.bootstrap_size = 0; } gf_sys_close(); return !e ? 0 : 1; }
int main (int argc, char **argv) { Double fps_dump; u32 i; char rad[500]; s32 frameID, h, m, s, f; Float fps; u32 dump_type; s32 dump_time; u32 dump_w, dump_h; Bool copy; char szConfigFile[4096]; char *dump_out; char *inName, *arg; GF_ISOFile *file; if (argc < 2) { PrintUsage(); return 0; } dump_type = 0; fps_dump = 0.0f; dump_w = dump_h = 0; dump_out = NULL; inName = NULL; frameID = -1; dump_time = -1; szConfigFile[0] = 0; for (i = 1; i < (u32) argc ; i++) { arg = argv[i]; if (arg[0] != '-') { inName = arg; break; } if (!stricmp(arg, "-h")) { PrintUsage(); return 0; } else if (!stricmp(arg, "-version")) { PrintVersion(); return 0; } else if (!stricmp(arg, "-size")) { sscanf(argv[i+1], "%dx%d", &dump_w, &dump_h); i++; } else if (!stricmp(arg, "-raw")) { dump_type = 2; if ((i+1<(u32)argc) && (argv[i+1][0]!='-')) { if (strstr(argv[i+1], "T")) { if (strstr(argv[i+1], "F")) { sscanf(argv[i+1], "T%d:%d:%d:%dF%f", &h, &m, &s, &f, &fps); dump_time = (s32) ((3600*h + 60*m + s)*1000 + 1000*f/fps); } else { sscanf(argv[i+1], "T%d:%d:%d", &h, &m, &s); dump_time = (s32) ((3600*h + 60*m + s)*1000); } } else { frameID = atoi(argv[i+1]); } i++; } } else if (!stricmp(arg, "-bmp")) { dump_type = 1; if ((i+1<(u32)argc) && (argv[i+1][0]!='-')) { if (strstr(argv[i+1], "T")) { if (strstr(argv[i+1], "F")) { sscanf(argv[i+1], "T%d:%d:%d:%dF%f", &h, &m, &s, &f, &fps); dump_time = (s32) ((3600*h + 60*m + s)*1000 + 1000*f/fps); } else { sscanf(argv[i+1], "T%d:%d:%d", &h, &m, &s); dump_time = (s32) ((3600*h + 60*m + s)*1000); } } else { frameID = atoi(argv[i+1]); } i++; } } else if (!stricmp(arg, "-3d")) { dump_type = 3; } else if (!stricmp(arg, "-outpath")) { dump_out = argv[i+1]; i++; } else if (!stricmp(arg, "-fps")) { fps_dump = atof(argv[i+1]); i++; } else if (!stricmp(arg, "-copy")) { copy = 1; } else if (!stricmp(arg, "-cfg")) { strcpy(szConfigFile, argv[i+1]); i += 1; } else { PrintUsage(); return (0); } } if (!inName) { PrintUsage(); return 0; } gf_sys_init(); file = gf_isom_open(inName, GF_ISOM_OPEN_READ, NULL); if (!file) { printf("Error opening file: %s\n", gf_error_to_string(gf_isom_last_error(NULL))); return 0; } if (dump_out) { arg = strrchr(inName, GF_PATH_SEPARATOR); if (arg) { strcpy(rad, arg + 1); } else { strcpy(rad, inName); } } else { strcpy(rad, inName); } while (rad[strlen(rad)-1] != '.') rad[strlen(rad)-1] = 0; rad[strlen(rad)-1] = 0; if (dump_type == 3) { bifs3d_viewpoints_merger(file, szConfigFile, dump_w, dump_h, rad, dump_type, dump_out, fps_dump, frameID, dump_time); } else bifs_to_vid(file, szConfigFile, dump_w, dump_h, rad, dump_type, dump_out, fps_dump, frameID, dump_time); printf("\ndone\n"); gf_isom_delete(file); return 0; }
int main(int argc, char **argv) { GF_ISOFile *movie; GF_ESD *esd; GF_Err e; Double gb_size = 5.0; u8 store_mode; u32 track, di, i, nb_samp; GF_ISOSample *samp; store_mode = GF_ISOM_OPEN_WRITE; for (i=1; i<argc; i++) { if (!strcmp(argv[i], "-flat")) store_mode = GF_ISOM_OPEN_WRITE; else if (!strcmp(argv[i], "-inter")) store_mode = GF_ISOM_WRITE_EDIT; else if (!strcmp(argv[i], "-size") && (i+1<argc)) { gb_size = atof(argv[i+1]); i++; } else if (!strcmp(argv[i], "-h")) { PrintUsage(); return 0; } } nb_samp = (u32) (gb_size*1024); fprintf(stdout, "Creating test file %s - %g GBytes - %d samples - %s mode\n", TEST_FILE_NAME, gb_size, nb_samp, (store_mode == GF_ISOM_OPEN_WRITE) ? "Flat" : "Interleaved"); movie = gf_isom_open(TEST_FILE_NAME, store_mode, NULL); if (!movie) { fprintf(stdout, "Error creating file: %s\n", gf_error_to_string(gf_isom_last_error(NULL))); return 1; } track = gf_isom_new_track(movie, 1, GF_ISOM_MEDIA_VISUAL, 25); esd = gf_odf_desc_esd_new(2); esd->decoderConfig->streamType = 4; gf_isom_new_mpeg4_description(movie, track, esd, NULL, NULL, &di); samp = gf_isom_sample_new(); samp->dataLength = 1024*1024; samp->data = gf_malloc(sizeof(char)*samp->dataLength); memset(samp->data, 0, sizeof(char)*samp->dataLength); for (i=0; i<nb_samp; i++) { if (samp->DTS % 25) samp->IsRAP = 0; else samp->IsRAP = 1; e = gf_isom_add_sample(movie, track, di, samp); samp->DTS += 1; fprintf(stdout, "Writing sample %d / %d \r", i+1, nb_samp); if (e) break; } gf_isom_sample_del(&samp); if (e) { fprintf(stdout, "\nError writing sample %d\n", i); gf_isom_delete(movie); return 1; } fprintf(stdout, "\nDone writing samples\n"); e = gf_isom_close(movie); if (e) { fprintf(stdout, "Error writing file\n"); return 1; } return 0; }
int dc_gpac_audio_moov_create(AudioOutputFile * p_aoutf, char * psz_name) { GF_Err ret; AVCodecContext * p_audio_codec_ctx = p_aoutf->p_codec_ctx; u32 di; u32 track; GF_M4ADecSpecInfo acfg; p_aoutf->p_isof = gf_isom_open(psz_name, GF_ISOM_OPEN_WRITE, NULL); if (!p_aoutf->p_isof) { fprintf(stderr, "Cannot open iso file %s\n", psz_name); return -1; } memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = GF_M4A_AAC_LC; acfg.base_sr = p_audio_codec_ctx->sample_rate; acfg.nb_chan = p_audio_codec_ctx->channels; acfg.sbr_object_type = 0; acfg.audioPL = gf_m4a_get_profile(&acfg); GF_ESD * p_esd = gf_odf_desc_esd_new(2); if (!p_esd) { fprintf(stderr, "Cannot create GF_ESD\n"); return -1; } p_esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); p_esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); p_esd->decoderConfig->streamType = GF_STREAM_AUDIO; p_esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; p_esd->decoderConfig->bufferSizeDB = 20; p_esd->slConfig->timestampResolution = p_audio_codec_ctx->sample_rate; p_esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); p_esd->ESID = 1; ret = gf_m4a_write_config(&acfg, &p_esd->decoderConfig->decoderSpecificInfo->data, &p_esd->decoderConfig->decoderSpecificInfo->dataLength); //gf_isom_store_movie_config(p_voutf->p_isof, 0); track = gf_isom_new_track(p_aoutf->p_isof, p_esd->ESID, GF_ISOM_MEDIA_AUDIO, p_audio_codec_ctx->sample_rate); //printf("TimeScale: %d \n", p_video_codec_ctx->time_base.den); if (!track) { fprintf(stderr, "Cannot create new track\n"); return -1; } ret = gf_isom_set_track_enabled(p_aoutf->p_isof, track, 1); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret)); return -1; } // if (!p_esd->ESID) p_esd->ESID = gf_isom_get_track_id(p_aoutf->p_isof, track); ret = gf_isom_new_mpeg4_description(p_aoutf->p_isof, track, p_esd, NULL, NULL, &di); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_new_mpeg4_description\n", gf_error_to_string(ret)); return -1; } gf_odf_desc_del((GF_Descriptor *) p_esd); p_esd = NULL; u8 bpsample = av_get_bytes_per_sample(p_aoutf->p_codec_ctx->sample_fmt) * 8; ret = gf_isom_set_audio_info(p_aoutf->p_isof, track, di, p_audio_codec_ctx->sample_rate, p_aoutf->p_codec_ctx->channels, bpsample); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_set_audio_info\n", gf_error_to_string(ret)); return -1; } ret = gf_isom_set_pl_indication(p_aoutf->p_isof, GF_ISOM_PL_AUDIO, acfg.audioPL); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_set_pl_indication\n", gf_error_to_string(ret)); return -1; } //printf("time scale: %d sample dur: %d \n", // p_video_codec_ctx->time_base.den, p_aoutf->p_codec_ctx->frame_size); ret = gf_isom_setup_track_fragment(p_aoutf->p_isof, track, 1, p_aoutf->p_codec_ctx->frame_size, 0, 0, 0, 0); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret)); return -1; } //gf_isom_add_track_to_root_od(p_voutf->p_isof,1); ret = gf_isom_finalize_for_fragment(p_aoutf->p_isof, 1); if (ret != GF_OK) { fprintf(stderr, "%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret)); return -1; } return 0; }
void isor_net_io(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; u32 size = 0; char *local_name; ISOMReader *read = (ISOMReader *) cbk; /*handle service message*/ gf_term_download_update_stats(read->dnload); if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { e = GF_EOS; } else if (param->msg_type==GF_NETIO_DATA_EXCHANGE) { e = GF_OK; size = param->size; } else { e = param->error; } if (e<GF_OK) { /*error opening service*/ if (!read->mov) gf_term_on_connect(read->service, NULL, e); return; } /*open file if not done yet (bad interleaving)*/ if (e==GF_EOS) { const char *local_name; if (read->mov) return; local_name = gf_dm_sess_get_cache_name(read->dnload); if (!local_name) { gf_term_on_connect(read->service, NULL, GF_SERVICE_ERROR); return; } e = GF_OK; read->mov = gf_isom_open(local_name, GF_ISOM_OPEN_READ, NULL); if (!read->mov) e = gf_isom_last_error(NULL); else read->time_scale = gf_isom_get_timescale(read->mov); gf_term_on_connect(read->service, NULL, GF_OK); if (read->no_service_desc) isor_declare_objects(read); } if (!size) return; /*service is opened, nothing to do*/ if (read->mov) return; /*try to open the service*/ local_name = (char *)gf_dm_sess_get_cache_name(read->dnload); if (!local_name) { gf_term_on_connect(read->service, NULL, GF_SERVICE_ERROR); return; } /*not enogh data yet*/ if (read->missing_bytes && (read->missing_bytes > size) ) { read->missing_bytes -= size; return; } e = gf_isom_open_progressive(local_name, 0, 0, &read->mov, &read->missing_bytes); switch (e) { case GF_ISOM_INCOMPLETE_FILE: return; case GF_OK: break; default: gf_term_on_connect(read->service, NULL, e); return; } read->frag_type = gf_isom_is_fragmented(read->mov) ? 1 : 0; /*ok let's go*/ read->time_scale = gf_isom_get_timescale(read->mov); gf_term_on_connect(read->service, NULL, GF_OK); if (read->no_service_desc) isor_declare_objects(read); }
void V4SceneGraph::LoadFile(const char *path) { GF_SceneLoader load; if (m_pSm) { gf_sr_set_scene(m_pSr, NULL); gf_sm_del(m_pSm); gf_sg_del(m_pSg); } // initializes a new scene // We need an GF_InlineScene, a SceneManager and an GF_ObjectManager m_pIs = gf_is_new(NULL); m_pSg = m_pIs->graph; m_pSm = gf_sm_new(m_pSg); m_pIs->root_od = gf_odm_new(); m_pIs->root_od->parentscene = NULL; m_pIs->root_od->subscene = m_pIs; m_pIs->root_od->term = m_term; m_term->root_scene = m_pIs; // TODO : what's the use of this ? if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); m_pOriginal_mp4 = NULL; /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = path; load.ctx = m_pSm; load.cbk = this; if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL); gf_sm_load_init(&load); gf_sm_load_run(&load); gf_sm_load_done(&load); if (load.isom) gf_isom_delete(load.isom); /* SceneManager should be initialized and filled correctly */ gf_sg_set_scene_size_info(m_pSg, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics); // TODO : replace with GetBifsStream GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0); if (sc->streamType == 3) { GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0); GF_Command *c = (GF_Command *) gf_list_get(au->commands,0); gf_sg_command_apply(m_pSg, c, 0); /* This is a patch to solve the save pb: When ApplyCommand is made on a Scene Replace Command The command node is set to NULL When we save a BIFS stream whose first command is of this kind, the file saver thinks the bifs commands should come from an NHNT file This is a temporary patch */ if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pSg->RootNode; } } gf_sr_set_scene(m_pSr, m_pSg); // retrieves all the node from the tree and adds them to the node pool GF_Node * root = gf_sg_get_root_node(m_pSg); CreateDictionnary(); }
GF_EXPORT GF_ISOMRTPStreamer *gf_isom_streamer_new(const char *file_name, const char *ip_dest, u16 port, Bool loop, Bool force_mpeg4, u32 path_mtu, u32 ttl, char *ifce_addr) { GF_ISOMRTPStreamer *streamer; GF_Err e = GF_OK; const char *opt = NULL; /*GF_Config *configFile = NULL; */ u32 i, max_ptime, au_sn_len; u8 payt; GF_ISOFile *file; GF_RTPTrack *track, *prev_track; u16 first_port; u32 nb_tracks; u32 sess_data_size; if (!ip_dest) ip_dest = "127.0.0.1"; if (!port) port = 7000; if (!path_mtu) path_mtu = 1450; GF_SAFEALLOC(streamer, GF_ISOMRTPStreamer); streamer->dest_ip = gf_strdup(ip_dest); payt = 96; max_ptime = au_sn_len = 0; file = gf_isom_open(file_name, GF_ISOM_OPEN_READ, NULL); if (!file) { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Error opening file %s: %s\n", opt, gf_error_to_string(gf_isom_last_error(NULL)))); return NULL; } streamer->isom = file; streamer->loop = loop; streamer->force_mpeg4_generic = force_mpeg4; first_port = port; sess_data_size = 0; prev_track = NULL; nb_tracks = gf_isom_get_track_count(streamer->isom); for (i=0; i<nb_tracks; i++) { u32 mediaSize, mediaDuration, flags, MinSize, MaxSize, avgTS, streamType, oti, const_dur, nb_ch, samplerate, maxDTSDelta, TrackMediaSubType, TrackMediaType, bandwidth, IV_length, KI_length, dsi_len; const char *url, *urn; char *dsi; Bool is_crypted; dsi_len = samplerate = streamType = oti = nb_ch = IV_length = KI_length = 0; is_crypted = 0; dsi = NULL; flags = 0; /*we only support self-contained files for hinting*/ gf_isom_get_data_reference(streamer->isom, i+1, 1, &url, &urn); if (url || urn) continue; TrackMediaType = gf_isom_get_media_type(streamer->isom, i+1); TrackMediaSubType = gf_isom_get_media_subtype(streamer->isom, i+1, 1); switch (TrackMediaType) { case GF_ISOM_MEDIA_TEXT: break; case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_SUBT: case GF_ISOM_MEDIA_OD: case GF_ISOM_MEDIA_SCENE: if (gf_isom_get_sample_description_count(streamer->isom, i+1) > 1) continue; break; default: continue; } GF_SAFEALLOC(track, GF_RTPTrack); if (prev_track) prev_track->next = track; else streamer->stream = track; prev_track = track; track->track_num = i+1; track->nb_aus = gf_isom_get_sample_count(streamer->isom, track->track_num); track->timescale = gf_isom_get_media_timescale(streamer->isom, track->track_num); mediaDuration = (u32)(gf_isom_get_media_duration(streamer->isom, track->track_num)*1000/track->timescale); // ms mediaSize = (u32)gf_isom_get_media_data_size(streamer->isom, track->track_num); sess_data_size += mediaSize; if (mediaDuration > streamer->duration_ms) streamer->duration_ms = mediaDuration; track->port = check_next_port(streamer, first_port); first_port = track->port+2; /*init packetizer*/ if (streamer->force_mpeg4_generic) flags = GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_FORCE_MPEG4; switch (TrackMediaSubType) { case GF_ISOM_SUBTYPE_MPEG4_CRYP: is_crypted = 1; case GF_ISOM_SUBTYPE_MPEG4: { GF_ESD *esd = gf_isom_get_esd(streamer->isom, track->track_num, 1); if (esd) { streamType = esd->decoderConfig->streamType; oti = esd->decoderConfig->objectTypeIndication; /*systems streams*/ if (streamType==GF_STREAM_AUDIO) { gf_isom_get_audio_info(streamer->isom, track->track_num, 1, &samplerate, &nb_ch, NULL); } /*systems streams*/ else if (streamType==GF_STREAM_SCENE) { if (gf_isom_has_sync_shadows(streamer->isom, track->track_num) || gf_isom_has_sample_dependency(streamer->isom, track->track_num)) flags |= GP_RTP_PCK_SYSTEMS_CAROUSEL; } if (esd->decoderConfig->decoderSpecificInfo) { dsi = esd->decoderConfig->decoderSpecificInfo->data; dsi_len = esd->decoderConfig->decoderSpecificInfo->dataLength; esd->decoderConfig->decoderSpecificInfo->data = NULL; esd->decoderConfig->decoderSpecificInfo->dataLength = 0; } gf_odf_desc_del((GF_Descriptor*)esd); } } break; case GF_ISOM_SUBTYPE_AVC_H264: case GF_ISOM_SUBTYPE_AVC2_H264: case GF_ISOM_SUBTYPE_SVC_H264: { GF_AVCConfig *avcc = gf_isom_avc_config_get(streamer->isom, track->track_num, 1); track->avc_nalu_size = avcc->nal_unit_size; gf_odf_avc_cfg_del(avcc); streamType = GF_STREAM_VISUAL; oti = GPAC_OTI_VIDEO_AVC; } break; default: streamType = GF_STREAM_4CC; oti = TrackMediaSubType; break; } /*get sample info*/ gf_media_get_sample_average_infos(streamer->isom, track->track_num, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); if (is_crypted) { Bool use_sel_enc; gf_isom_get_ismacryp_info(streamer->isom, track->track_num, 1, NULL, NULL, NULL, NULL, NULL, &use_sel_enc, &IV_length, &KI_length); if (use_sel_enc) flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION; } track->rtp = gf_rtp_streamer_new_extended(streamType, oti, track->timescale, (char *) streamer->dest_ip, track->port, path_mtu, ttl, ifce_addr, flags, dsi, dsi_len, payt, samplerate, nb_ch, is_crypted, IV_length, KI_length, MinSize, MaxSize, avgTS, maxDTSDelta, const_dur, bandwidth, max_ptime, au_sn_len); if (!track->rtp) { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Could not initialize RTP streamer: %s\n", gf_error_to_string(e))); goto exit; } payt++; track->microsec_ts_scale = 1000000; track->microsec_ts_scale /= gf_isom_get_media_timescale(streamer->isom, track->track_num); } return streamer; exit: gf_free(streamer); return NULL; }
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; }
int dc_gpac_audio_moov_create(AudioOutputFile *audio_output_file, char *filename) { GF_Err ret; u32 di, track; u8 bpsample; GF_ESD *esd; #ifndef GPAC_DISABLE_AV_PARSERS GF_M4ADecSpecInfo acfg; #endif AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; audio_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); if (!audio_output_file->isof) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); return -1; } esd = gf_odf_desc_esd_new(2); if (!esd) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create GF_ESD\n")); return -1; } esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); esd->decoderConfig->streamType = GF_STREAM_AUDIO; if (!strcmp(audio_output_file->codec_ctx->codec->name, "aac")) { //TODO: find an automatic table esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; esd->decoderConfig->bufferSizeDB = 20; esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->ESID = 1; #ifndef GPAC_DISABLE_AV_PARSERS memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = GF_M4A_AAC_LC; acfg.base_sr = audio_codec_ctx->sample_rate; acfg.nb_chan = audio_codec_ctx->channels; acfg.sbr_object_type = 0; acfg.audioPL = gf_m4a_get_profile(&acfg); ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); assert(ret == GF_OK); #endif } else { if (strcmp(audio_output_file->codec_ctx->codec->name, "mp2")) { GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unlisted codec, setting GPAC_OTI_AUDIO_MPEG1 descriptor.\n")); } esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; esd->decoderConfig->bufferSizeDB = 20; esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->ESID = 1; #ifndef GPAC_DISABLE_AV_PARSERS memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); acfg.base_object_type = GF_M4A_LAYER2; acfg.base_sr = audio_codec_ctx->sample_rate; acfg.nb_chan = audio_codec_ctx->channels; acfg.sbr_object_type = 0; acfg.audioPL = gf_m4a_get_profile(&acfg); ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); assert(ret == GF_OK); #endif } //gf_isom_store_movie_config(video_output_file->isof, 0); track = gf_isom_new_track(audio_output_file->isof, esd->ESID, GF_ISOM_MEDIA_AUDIO, audio_codec_ctx->sample_rate); GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("TimeScale: %d \n", audio_codec_ctx->time_base.den)); if (!track) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); return -1; } ret = gf_isom_set_track_enabled(audio_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; } // if (!esd->ESID) esd->ESID = gf_isom_get_track_id(audio_output_file->isof, track); ret = gf_isom_new_mpeg4_description(audio_output_file->isof, track, esd, NULL, NULL, &di); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_new_mpeg4_description\n", gf_error_to_string(ret))); return -1; } gf_odf_desc_del((GF_Descriptor *) esd); esd = NULL; bpsample = av_get_bytes_per_sample(audio_output_file->codec_ctx->sample_fmt) * 8; ret = gf_isom_set_audio_info(audio_output_file->isof, track, di, audio_codec_ctx->sample_rate, audio_output_file->codec_ctx->channels, bpsample); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_audio_info\n", gf_error_to_string(ret))); return -1; } #ifndef GPAC_DISABLE_AV_PARSERS ret = gf_isom_set_pl_indication(audio_output_file->isof, GF_ISOM_PL_AUDIO, acfg.audioPL); if (ret != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_pl_indication\n", gf_error_to_string(ret))); return -1; } #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("time scale: %d sample dur: %d \n", audio_codec_ctx->time_base.den, audio_output_file->codec_ctx->frame_size)); ret = gf_isom_setup_track_fragment(audio_output_file->isof, track, 1, audio_output_file->codec_ctx->frame_size, 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(audio_output_file->isof, 1); 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(audio_output_file->isof, track, audio_output_file->audio_data_conf->codec6381, GF_FALSE, GF_FALSE); if (ret != GF_OK) return -1; return 0; }