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

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); }
participants (1)
-
syncmail@mplayerhq.hu