예제 #1
0
파일: read.c 프로젝트: supperlitt/gpac
GF_Err ISOR_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
    char szURL[2048];
    char *tmp;
    ISOMReader *read;
    if (!plug || !plug->priv || !serv) return GF_SERVICE_ERROR;
    read = (ISOMReader *) plug->priv;

    read->input = plug;
    read->service = serv;

    if (read->dnload) gf_term_download_del(read->dnload);
    read->dnload = NULL;

    read->base_track_id = 0;
    strcpy(szURL, url);
    tmp = strrchr(szURL, '.');
    if (tmp) {
        tmp = strchr(tmp, '#');
        if (tmp) {
            if (!strnicmp(tmp, "#trackID=", 9)) {
                read->base_track_id = atoi(tmp+9);
            } else {
                read->base_track_id = atoi(tmp+1);
            }
            tmp[0] = 0;
        }
    }

    if (isor_is_local(szURL)) {
        GF_Err e;
        u64 start_range, end_range;
        start_range = end_range = 0;
        if (plug->query_proxy) {
            GF_NetworkCommand param;
            param.command_type = GF_NET_SERVICE_QUERY_INIT_RANGE;
            if (read->input->query_proxy(read->input, &param)==GF_OK) {
                start_range = param.url_query.start_range;
                end_range = param.url_query.end_range;
            }
        }
        e = gf_isom_open_progressive(szURL, start_range, end_range, &read->mov, &read->missing_bytes);
        if (e != GF_OK) {
            GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[IsoMedia] : error while opening %s, error=%s\n", szURL, gf_error_to_string(e)));
            gf_term_on_connect(serv, NULL, e);
            return GF_OK;
        }
        read->frag_type = gf_isom_is_fragmented(read->mov) ? 1 : 0;

        read->time_scale = gf_isom_get_timescale(read->mov);
        /*reply to user*/
        gf_term_on_connect(serv, NULL, GF_OK);
        if (read->no_service_desc) isor_declare_objects(read);
    } else {
        /*setup downloader*/
        isor_setup_download(plug, szURL);
    }
    return GF_OK;
}
예제 #2
0
GPACDemuxMP4Simple::GPACDemuxMP4Simple(std::string const& path)
	: reader(new ISOFileReader) {
	GF_ISOFile *movie;
	u64 missingBytes;
	GF_Err e = gf_isom_open_progressive(path.c_str(), 0, 0, &movie, &missingBytes);
	if ((e != GF_OK && e != GF_ISOM_INCOMPLETE_FILE) || movie == nullptr) {
		throw error(format("Could not open file %s for reading (%s).", path, gf_error_to_string(e)));
	}
	reader->init(movie);
	output = addOutput(new OutputDefault);
}
예제 #3
0
파일: read.c 프로젝트: supperlitt/gpac
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);
}
예제 #4
0
int main(int argc, char **argv)
{
	/* The ISO progressive reader */
	GF_ISOFile *movie;
	/* Error indicator */
	GF_Err e;
	/* Number of bytes required to finish the current ISO Box reading */
	u64 missing_bytes;
	/* Return value for the program */
	int ret = 0;
	/* Maximum index of the segments*/
	u32 seg_max = argc-2;
	/* Number of the segment being processed*/
	u32 seg_curr = 0;
	u32 track_id = 1;
	u32 sample_index = 1;

	/* Usage */
	if (argc < 2) {
		fprintf(stdout, "Usage: %s filename0 [filename1 filename2 ...]\n", argv[0]);
		return 1;
	}

#if defined(DEBUG) || defined(_DEBUG)
	/* Enables GPAC memory tracking in debug mode only */
	gf_sys_init(GF_TRUE);
	gf_log_set_tool_level(GF_LOG_CONTAINER, GF_LOG_INFO);
	gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
#endif

	/* First or init segment */
	fprintf(stdout, "Process segment %5d/%5d: %s\n", seg_curr, seg_max, argv[seg_curr+1]);
	e = gf_isom_open_progressive(argv[seg_curr+1], 0, 0, &movie, &missing_bytes);
	if ((e != GF_OK && e != GF_ISOM_INCOMPLETE_FILE) || movie == NULL) {
		fprintf(stdout, "Could not open file %s for reading (%s).\n", argv[seg_curr+1], gf_error_to_string(e));
		return 1;
	}
	process_samples_from_track(movie, track_id, &sample_index);
	seg_curr++;

	/* Process segments */
	while (seg_curr <= seg_max) {
		fprintf(stdout, "Process segment %5d/%5d: %s\n", seg_curr, seg_max, argv[seg_curr+1]);

		/* Open the segment */
		e = gf_isom_open_segment(movie, argv[seg_curr+1], 0, 0, GF_FALSE);
		if (e != GF_OK) {
			fprintf(stdout, "Could not open segment %s for reading (%s).\n", argv[seg_curr+1], gf_error_to_string(e));
			ret = 1;
			goto exit;
		}

		/* Process the segment */
		process_samples_from_track(movie, track_id, &sample_index);

		/* Release the segment */
		gf_isom_release_segment(movie, 1);

		seg_curr++;
	}

exit:
	fprintf(stdout, "Total nb Samples: %d\n", gf_isom_get_sample_count(movie, gf_isom_get_track_by_id(movie, track_id) ) );
	gf_isom_release_segment(movie, 1);
	gf_isom_close(movie);
#if defined(DEBUG) || defined(_DEBUG)
	/* Closes GPAC memory tracking in debug mode only */
	gf_sys_close();
#endif

	return ret;
}
예제 #5
0
파일: read.c 프로젝트: dragonlucian/gpac
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);
}
예제 #6
0
파일: main.c 프로젝트: JamesLinus/gpac
int main(int argc, char **argv)
{
	/* The ISO progressive reader */
	ISOProgressiveReader reader;
	/* Error indicator */
	GF_Err e;
	/* input file to be read in the data buffer */
	FILE *input;
	/* number of bytes read from the file at each read operation */
	u32 read_bytes;
	/* number of bytes read from the file (total) */
	u64 total_read_bytes;
	/* size of the input file */
	u64 file_size;
	/* number of bytes required to finish the current ISO Box reading (not used here)*/
	u64 missing_bytes;
	/* Thread used to run the ISO parsing in */
	GF_Thread *reading_thread;
	/* Return value for the program */
	int ret = 0;

	/* Usage */
	if (argc != 2) {
		fprintf(stdout, "Usage: %s filename\n", argv[0]);
		return 1;
	}

	/* Initializing GPAC framework */
	/* Enables GPAC memory tracking in debug mode only */
#if defined(DEBUG) || defined(_DEBUG)
	gf_sys_init(GF_MemTrackerSimple);
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);
	gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
#else
	gf_sys_init(GF_MemTrackerNone);
	gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);
#endif

	/* This is an input file to read data from. Could be replaced by any other method to retrieve the data (e.g. JavaScript, socket, ...)*/
	input = gf_fopen(argv[1], "rb");
	if (!input) {
		fprintf(stdout, "Could not open file %s for reading.\n", argv[1]);
		gf_sys_close();
		return 1;
	}

	gf_fseek(input, 0, SEEK_END);
	file_size = gf_ftell(input);
	gf_fseek(input, 0, SEEK_SET);

	/* Initializing the progressive reader */
	memset(&reader, 0, sizeof(ISOProgressiveReader));
	reading_thread = gf_th_new("ISO reading thread");
	reader.mutex = gf_mx_new("ISO Segment");
	reader.do_run = GF_TRUE;
	/* we want to parse the first track */
	reader.track_id = 1;
	/* start the async parsing */
	gf_th_run(reading_thread, iso_progressive_read_thread, &reader);

	/* start the data reading */
	reader.data_size = BUFFER_BLOCK_SIZE;
	reader.data = (u8 *)gf_malloc(reader.data_size);
	reader.valid_data_size = 0;
	total_read_bytes = 0;
	while (1) {
		/* block the parser until we are done manipulating the data buffer */
		gf_mx_p(reader.mutex);

		if (reader.valid_data_size + BUFFER_BLOCK_SIZE > MAX_BUFFER_SIZE) {
			/* regulate the reader to limit the max buffer size and let some time to the parser to release buffer data */
			fprintf(stdout, "Buffer full (%d/%d)- waiting to read next data \r", reader.valid_data_size, reader.data_size);
			gf_mx_v(reader.mutex);
			//gf_sleep(10);
		} else {
			/* make sure we have enough space in the buffer to read the next bloc of data */
			if (reader.valid_data_size + BUFFER_BLOCK_SIZE > reader.data_size) {
				reader.data = (u8 *)gf_realloc(reader.data, reader.data_size + BUFFER_BLOCK_SIZE);
				reader.data_size += BUFFER_BLOCK_SIZE;
			}

			/* read the next bloc of data and update the data buffer url */
			read_bytes = fread(reader.data+reader.valid_data_size, 1, BUFFER_BLOCK_SIZE, input);
			total_read_bytes += read_bytes;
			fprintf(stdout, "Read "LLD" bytes of "LLD" bytes from input file %s (buffer status: %5d/%5d)\r", total_read_bytes, file_size, argv[1], reader.valid_data_size, reader.data_size);
			if (read_bytes) {
				reader.valid_data_size += read_bytes;
				sprintf(reader.data_url, "gmem://%d@%p", reader.valid_data_size, reader.data);
			} else {
				/* end of file we can quit */
				gf_mx_v(reader.mutex);
				break;
			}

			/* if the file is not yet opened (no movie), open it in progressive mode (to update its data later on) */
			if (!reader.movie) {
				/* let's initialize the parser */
				e = gf_isom_open_progressive(reader.data_url, 0, 0, &reader.movie, &missing_bytes);
				if (reader.movie) {
					gf_isom_set_single_moof_mode(reader.movie, GF_TRUE);
				}
				/* we can let parser try to work now */
				gf_mx_v(reader.mutex);

				if ((e == GF_OK || e == GF_ISOM_INCOMPLETE_FILE) && reader.movie) {
					/* nothing to do, this is normal */
				} else {
					fprintf(stdout, "Error opening fragmented mp4 in progressive mode: %s (missing "LLD" bytes)\n", gf_error_to_string(e), missing_bytes);
					ret = 1;
					goto exit;
				}
			} else {
				/* let inform the parser that the buffer has been updated with new data */
				e = gf_isom_refresh_fragmented(reader.movie, &missing_bytes, reader.data_url);

				/* we can let parser try to work now */
				gf_mx_v(reader.mutex);

				if (e != GF_OK && e != GF_ISOM_INCOMPLETE_FILE) {
					fprintf(stdout, "Error refreshing fragmented mp4: %s (missing "LLD" bytes)\n", gf_error_to_string(e), missing_bytes);
					ret = 1;
					goto exit;
				}
			}

			//gf_sleep(1);
		}
	}

exit:
	/* stop the parser */
	reader.do_run = GF_FALSE;
	gf_th_stop(reading_thread);

	/* clean structures */
	gf_th_del(reading_thread);
	gf_mx_del(reader.mutex);
	gf_free(reader.data);
	gf_isom_close(reader.movie);
	gf_fclose(input);
	gf_sys_close();

	return ret;
}