[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