[NUT-devel] [NUT] (ods15): r91 - in /trunk: demux_nut.c libnut/demuxer.c libnut/muxer.c libnut/nut.h libnut/priv.h nututils/demux_nut.c

syncmail at mplayerhq.hu syncmail at mplayerhq.hu
Sat Mar 11 13:10:33 CET 2006


Author: ods15
Date: Sat Mar 11 13:10:33 2006
New Revision: 91

Log:
sync to spec, forward_ptr has its own checksum.
API change, nut_read_headers() must be called first.

Modified:
    trunk/demux_nut.c
    trunk/libnut/demuxer.c
    trunk/libnut/muxer.c
    trunk/libnut/nut.h
    trunk/libnut/priv.h
    trunk/nututils/demux_nut.c

Modified: trunk/demux_nut.c
==============================================================================
--- trunk/demux_nut.c (original)
+++ trunk/demux_nut.c Sat Mar 11 13:10:33 2006
@@ -52,6 +52,7 @@
 
 	if (memcmp(buf, ID_STRING, ID_LENGTH)) return 0;
 
+	stream_seek(demuxer->stream, 0);
 	return DEMUXER_TYPE_NUT;
 }
 
@@ -63,28 +64,17 @@
 			.seek = mp_seek,
 			.read = mp_read,
 			.eof = NULL,
-			.file_pos = ID_LENGTH,
+			.file_pos = stream_tell(demuxer->stream),
 		},
 		.read_index = index_mode
 	};
 	nut_priv_t * priv = demuxer->priv;
 	nut_context_t * nut = priv->nut = nut_demuxer_init(&dopts);
-	nut_packet_t pd;
 	nut_stream_header_t * s;
 	int ret;
 	int i;
 
-	while ((ret = nut_read_next_packet(nut, &pd))) {
-		if (ret < 0) mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", nut_error(-ret));
-		if (ret == 1) break;
-	}
-	if (ret || pd.type != e_headers)  {
-		nut_demuxer_uninit(nut);
-		free(priv);
-		return NULL;
-	}
-
-	if ((ret = nut_read_headers(nut, &pd,  &s))) {
+	if ((ret = nut_read_headers(nut, &s))) {
 		if (ret < 0) mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", nut_error(-ret));
 		nut_demuxer_uninit(nut);
 		free(priv);

Modified: trunk/libnut/demuxer.c
==============================================================================
--- trunk/libnut/demuxer.c (original)
+++ trunk/libnut/demuxer.c Sat Mar 11 13:10:33 2006
@@ -71,6 +71,12 @@
 	return 0;
 }
 
+static uint8_t * get_buf(input_buffer_t * bc, off_t start) {
+	start -= bc->file_pos;
+	assert((unsigned)start < bc->read_len);
+	return bc->buf + start;
+}
+
 static input_buffer_t * new_mem_buffer() {
 	input_buffer_t * bc = malloc(sizeof(input_buffer_t));
 	bc->read_len = 0;
@@ -187,33 +193,40 @@
 	return 0;
 }
 
-static int get_header(input_buffer_t * in, input_buffer_t * out, int len) {
-	uint64_t code;
-
-	assert(out->is_mem);
-	assert(out->buf == out->buf_ptr);
-
-	len -= 4; // checksum
-
-	if (out->write_len < len) {
-		out->write_len = len;
-		out->buf_ptr = out->buf = realloc(out->buf, out->write_len);
-	}
-	if (get_data(in, len, out->buf) != len) return buf_eof(in);
-	out->read_len = len;
-
-	if (get_bytes(in, 4, &code)) return buf_eof(in); // checksum
-	if (code != crc32(out->buf, len)) return -ERR_BAD_CHECKSUM;
-
-	return 0;
-}
-
-static int get_main_header(nut_context_t *nut, int len) {
+static int get_header(input_buffer_t * in, input_buffer_t * out) {
+	off_t start = bctello(in) - 8; // startcode
+	int forward_ptr;
+	int err = 0;
+
+	GET_V(in, forward_ptr);
+	if (forward_ptr > 4096) {
+		skip_buffer(in, 4); // header_checksum
+		ERROR(crc32(get_buf(in, start), bctello(in) - start), -ERR_BAD_CHECKSUM);
+	}
+
+	CHECK(skip_buffer(in, forward_ptr));
+	ERROR(crc32(in->buf_ptr - forward_ptr, forward_ptr), -ERR_BAD_CHECKSUM);
+
+	if (out) {
+		assert(out->is_mem);
+		assert(out->buf == out->buf_ptr);
+		if (out->write_len < forward_ptr - 4) {
+			out->write_len = forward_ptr - 4;
+			out->buf_ptr = out->buf = realloc(out->buf, out->write_len);
+		}
+		memcpy(out->buf, in->buf_ptr - forward_ptr, forward_ptr - 4);
+		out->read_len = forward_ptr - 4; // not including checksum
+	}
+err_out:
+	return err;
+}
+
+static int get_main_header(nut_context_t * nut) {
 	input_buffer_t * tmp = new_mem_buffer();
 	int i, j, err = 0;
 	int flag, fields, timestamp = 0, mul = 1, stream = 0, sflag, size, count, reserved;
 
-	CHECK(get_header(nut->i, tmp, len));
+	CHECK(get_header(nut->i, tmp));
 
 	GET_V(tmp, i);
 	ERROR(i != NUT_VERSION, -ERR_BAD_VERSION);
@@ -264,11 +277,10 @@
 static int get_stream_header(nut_context_t * nut, int id) {
 	input_buffer_t * tmp = new_mem_buffer();
 	stream_context_t * sc = &nut->sc[id];
-	int i, err = 0, len;
+	int i, err = 0;
 	uint64_t a;
 
-	GET_V(nut->i, len);
-	CHECK(get_header(nut->i, tmp, len));
+	CHECK(get_header(nut->i, tmp));
 
 	GET_V(tmp, i);
 	ERROR(i != id, -ERR_BAD_STREAM_ORDER);
@@ -401,8 +413,7 @@
 	CHECK(get_bytes(nut->i, 8, &x));
 	ERROR(x != INDEX_STARTCODE, -ERR_GENERAL_ERROR);
 
-	GET_V(nut->i, x);
-	CHECK(get_header(nut->i, tmp, x));
+	CHECK(get_header(nut->i, tmp));
 
 	GET_V(tmp, x);
 	for (i = 0; i < nut->stream_count; i++) {
@@ -655,24 +666,7 @@
 
 int nut_read_next_packet(nut_context_t * nut, nut_packet_t * pd) {
 	int err = 0;
-	uint64_t tmp;
-	if (!nut->last_headers) {
-		const int len = strlen(ID_STRING) + 1;
-		char str[len];
-		ERROR(get_data(nut->i, len, str) != len, buf_eof(nut->i));
-		if (memcmp(str, ID_STRING, len)) nut->i->buf_ptr = nut->i->buf; // rewind
-		CHECK(get_bytes(nut->i, 8, &tmp));
-		do {
-			if (tmp == MAIN_STARTCODE) {
-				GET_V(nut->i, pd->len);
-				pd->type = e_headers;
-				return 0;
-			}
-			ERROR(ready_read_buf(nut->i, 1) < 1, buf_eof(nut->i));
-			tmp = (tmp << 8) | *(nut->i->buf_ptr++);
-		} while (bctello(nut->i) < 4096);
-	}
-	ERROR(!nut->last_headers, -ERR_NO_HEADERS);
+	ERROR(!nut->last_headers, -ERR_NO_HEADERS); // paranoia, old API
 
 	if (nut->seek_status) { // in error mode!
 		syncpoint_t s;
@@ -702,11 +696,32 @@
 	return err;
 }
 
-int nut_read_headers(nut_context_t * nut, nut_packet_t * pd, nut_stream_header_t * s []) {
+int nut_read_headers(nut_context_t * nut, nut_stream_header_t * s []) {
 	int i, err = 0;
 	*s = NULL;
-	if (!nut->last_headers) { // we already have headers, we were called just for index
-		CHECK(get_main_header(nut, pd->len));
+	if (!nut->seek_status) { // we already have headers, we were called just for index
+		if (!nut->last_headers) {
+			off_t start = bctello(nut->i);
+			uint64_t tmp;
+			if (start < strlen(ID_STRING) + 1) {
+				int n = strlen(ID_STRING) + 1 - start;
+				ERROR(ready_read_buf(nut->i, n) < n, buf_eof(nut->i));
+				if (memcmp(get_buf(nut->i, start), ID_STRING + start, n)) nut->i->buf_ptr = nut->i->buf; // rewind
+				fprintf(stderr, "NUT file_id checks out\n");
+			}
+
+			CHECK(get_bytes(nut->i, 7, &tmp));
+			ERROR(ready_read_buf(nut->i, 4096) < 4096, buf_eof(nut->i));
+			while (bctello(nut->i) < 4096) {
+				tmp = (tmp << 8) | *(nut->i->buf_ptr++);
+				if (tmp == MAIN_STARTCODE) break;
+			}
+			ERROR(tmp != MAIN_STARTCODE, -ERR_NO_HEADERS);
+			nut->last_headers = bctello(nut->i);
+			flush_buf(nut->i);
+		}
+
+		CHECK(get_main_header(nut));
 
 		if (!nut->sc) {
 			nut->sc = malloc(sizeof(stream_context_t) * nut->stream_count);
@@ -741,7 +756,6 @@
 			nut->i->buf_ptr -= 8;
 			flush_buf(nut->i);
 		}
-		nut->last_headers = 1;
 	}
 
 	if (nut->dopts.read_index && nut->i->isc.seek) {

Modified: trunk/libnut/muxer.c
==============================================================================
--- trunk/libnut/muxer.c (original)
+++ trunk/libnut/muxer.c Sat Mar 11 13:10:33 2006
@@ -107,21 +107,28 @@
 	put_data(bc, len, data);
 }
 
-static void put_header(output_buffer_t * bc, output_buffer_t * tmp, uint64_t startcode, int index_ptr) {
+static void put_header(output_buffer_t * bc, output_buffer_t * in, output_buffer_t * tmp, uint64_t startcode, int index_ptr) {
 	int forward_ptr;
+	assert(in->is_mem);
 	assert(tmp->is_mem);
-
-	forward_ptr = tmp->buf_ptr - tmp->buf;
+	clear_buffer(tmp);
+
+	forward_ptr = bctello(in);
 	forward_ptr += 4; // checksum
 	if (index_ptr) forward_ptr += 8;
-	fprintf(stderr, "header/index size: %d\n", forward_ptr + 8 + v_len(forward_ptr));
-
-	if (index_ptr) put_bytes(tmp, 8, 8 + v_len(forward_ptr) + forward_ptr);
-
-	put_bytes(bc, 8, startcode);
-	put_v(bc, forward_ptr);
-	put_data(bc, tmp->buf_ptr - tmp->buf, tmp->buf);
-	put_bytes(bc, 4, crc32(tmp->buf, tmp->buf_ptr - tmp->buf));
+
+	// packet_header
+	put_bytes(tmp, 8, startcode);
+	put_v(tmp, forward_ptr);
+	if (forward_ptr > 4096) put_bytes(tmp, 4, crc32(tmp->buf, bctello(tmp)));
+	put_data(bc, bctello(tmp), tmp->buf);
+
+	// packet_footer
+	if (index_ptr) put_bytes(in, 8, bctello(tmp) + bctello(in) + 8 + 4);
+	put_bytes(in, 4, crc32(in->buf, bctello(in)));
+
+	put_data(bc, bctello(in), in->buf);
+	if (startcode != SYNCPOINT_STARTCODE) fprintf(stderr, "header/index size: %d\n", (int)(bctello(tmp) + bctello(in)));
 }
 
 static void put_main_header(nut_context_t * nut) {
@@ -168,7 +175,7 @@
 		if (fields > 6) put_v(tmp, count);
 	}
 
-	put_header(nut->o, tmp, MAIN_STARTCODE, 0);
+	put_header(nut->o, tmp, nut->tmp_buffer2, MAIN_STARTCODE, 0);
 }
 
 static void put_stream_header(nut_context_t * nut, int id) {
@@ -201,7 +208,7 @@
 			break;
 	}
 
-	put_header(nut->o, tmp, STREAM_STARTCODE, 0);
+	put_header(nut->o, tmp, nut->tmp_buffer2, STREAM_STARTCODE, 0);
 }
 
 static void put_info(nut_context_t * nut, nut_info_packet_t * info) {
@@ -239,7 +246,7 @@
 		}
 	}
 
-	put_header(nut->o, tmp, INFO_STARTCODE, 0);
+	put_header(nut->o, tmp, nut->tmp_buffer2, INFO_STARTCODE, 0);
 }
 
 static void put_headers(nut_context_t * nut) {
@@ -373,7 +380,7 @@
 		}
 	}
 
-	put_header(nut->o, tmp, INDEX_STARTCODE, 1);
+	put_header(nut->o, tmp, nut->tmp_buffer2, INDEX_STARTCODE, 1);
 }
 
 static int frame_header(nut_context_t * nut, const nut_packet_t * fd, int * rftnum) {
@@ -496,6 +503,7 @@
 
 	nut->o = new_output_buffer(mopts->output);
 	nut->tmp_buffer = new_mem_buffer(); // general purpose buffer
+	nut->tmp_buffer2 = new_mem_buffer(); //  for packet_headers
 	nut->max_distance = mopts->max_distance;
 	nut->mopts = *mopts;
 
@@ -651,6 +659,7 @@
 	free(nut->syncpoints.eor);
 
 	free_buffer(nut->tmp_buffer);
+	free_buffer(nut->tmp_buffer2);
 	free_buffer(nut->o); // flushes file
 	fprintf(stderr, "TOTAL: %d bytes data, %d bytes overhead, %.2lf%% overhead\n", total,
 		(int)ftell(nut->mopts.output.priv) - total, (double)(ftell(nut->mopts.output.priv) - total) / total*100);

Modified: trunk/libnut/nut.h
==============================================================================
--- trunk/libnut/nut.h (original)
+++ trunk/libnut/nut.h Sat Mar 11 13:10:33 2006
@@ -161,11 +161,10 @@
 len is the amount of bytes that are LEFT, not the ones read. */
 int nut_skip_packet(nut_context_t * nut, int * len);
 
-/** Read headers, must be called ONLY after read_next_packet
-gave e_headers.
+/** Read headers, must be called at begginning
 @brief "s" is malloced and needs to be free'd.
 */
-int nut_read_headers(nut_context_t * nut, nut_packet_t * pd, nut_stream_header_t * s []);
+int nut_read_headers(nut_context_t * nut, nut_stream_header_t * s []);
 
 /** Just reads the frame DATA. all it's header has already been
 read by nut_read_next_packet. buf must be allocated and big enough.

Modified: trunk/libnut/priv.h
==============================================================================
--- trunk/libnut/priv.h (original)
+++ trunk/libnut/priv.h Sat Mar 11 13:10:33 2006
@@ -118,6 +118,7 @@
 	input_buffer_t * i;
 	output_buffer_t * o;
 	output_buffer_t * tmp_buffer;
+	output_buffer_t * tmp_buffer2;
 
 	int stream_count;
 	stream_context_t * sc;

Modified: trunk/nututils/demux_nut.c
==============================================================================
--- trunk/nututils/demux_nut.c (original)
+++ trunk/nututils/demux_nut.c Sat Mar 11 13:10:33 2006
@@ -23,12 +23,7 @@
 
 static int read_headers(void * priv, nut_stream_header_t ** nut_streams) {
 	nutmerge_nut_t * nut = priv;
-	nut_packet_t tmp;
-	int err;
-	if ((err = nut_read_next_packet(nut->nut, &tmp))) goto err_out;
-	if (tmp.type != e_headers) return 2;
-	err = nut_read_headers(nut->nut, &tmp, nut_streams);
-err_out:
+	int err = nut_read_headers(nut->nut, nut_streams);
 	return err == 1 ? -1 : ABS(err);
 }
 




More information about the NUT-devel mailing list