[NUT-devel] [nut]: r225 - in trunk: libnut/Makefile libnut/framecode.c libnut/libnut.h libnut/muxer.c nututils/nutmerge.c
ods15
subversion at mplayerhq.hu
Fri Nov 17 17:52:05 CET 2006
Author: ods15
Date: Fri Nov 17 17:52:04 2006
New Revision: 225
Added:
trunk/libnut/framecode.c
Modified:
trunk/libnut/Makefile
trunk/libnut/libnut.h
trunk/libnut/muxer.c
trunk/nututils/nutmerge.c
Log:
Add framecode table generator, based on guesses on codecs
Modified: trunk/libnut/Makefile
==============================================================================
--- trunk/libnut/Makefile (original)
+++ trunk/libnut/Makefile Fri Nov 17 17:52:04 2006
@@ -1,5 +1,7 @@
include ../config.mak
+OBJS = muxer.o demuxer.o reorder.o framecode.o
+
all: libnut.a
install:
@@ -12,12 +14,12 @@
rm -f $(prefix)/lib/libnut.a
rm -f $(prefix)/include/libnut.h
-libnut.a: muxer.o demuxer.o reorder.o
+libnut.a: ${OBJS}
rm -f $@
${AR} rc $@ $^
$(RANLIB) $@
-libnut.so: muxer.o demuxer.o reorder.o
+libnut.so: ${OBJS}
${CC} ${CFLAGS} -shared $^ -o $@
.c.o: priv.h nut.h
Added: trunk/libnut/framecode.c
==============================================================================
--- (empty file)
+++ trunk/libnut/framecode.c Fri Nov 17 17:52:04 2006
@@ -0,0 +1,127 @@
+// (C) 2005-2006 Oded Shimon
+// This file is available under the MIT/X license, see COPYING
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "libnut.h"
+#include "priv.h"
+
+typedef nut_frame_table_input_t fti_t; // just a shortcut
+
+static int count_streams(const nut_stream_header_t * s) {
+ int i;
+ for (i = 0; s[i].type != -1; i++);
+ return i;
+}
+
+void nut_framecode_generate(const nut_stream_header_t s[], nut_frame_table_input_t fti[256]) {
+ int stream_count = count_streams(s);
+ int i, n = 0, m = 0, tot_con = 0;
+ enum {
+ e_consume_none = 0,
+ e_consume_mpeg4,
+ e_consume_h264,
+ e_consume_video,
+ e_consume_vorbis,
+ } consume[stream_count];
+
+ for (i = 0; i < stream_count; i++) consume[i] = e_consume_none;
+
+ // the basic framecodes. flag, pts, stream, mul, size, count
+ fti[n++] = (fti_t){ /*invalid 0x00*/ FLAG_INVALID, 0, 0, 1, 0, 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_CODED_PTS|FLAG_STREAM_ID|FLAG_SIZE_MSB, 0, 0, 1, 0, 1 };
+ fti[n++] = (fti_t){ FLAG_CODED_PTS|FLAG_STREAM_ID|FLAG_SIZE_MSB, 0, 0, 1, 0, 1 };
+ fti[n++] = (fti_t){ /*extreme fallback*/ FLAG_CODED, 1, 0, 1, 0, 1 };
+
+ for (i = 0; i < stream_count; i++) {
+ if (n + m > 230) break; // that's enough! don't overflow
+ switch (s[i].type) {
+ case NUT_VIDEO_CLASS:
+ fti[n++] = (fti_t){ NUT_FLAG_KEY| FLAG_SIZE_MSB, 1, i, 1, 0, 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_CHECKSUM|FLAG_SIZE_MSB, 1, i, 1, 0, 1 };
+ fti[n++] = (fti_t){ FLAG_CODED_PTS|FLAG_SIZE_MSB, 0, i, 1, 0, 1 };
+ if (s[i].fourcc_len == 4 && !strncmp(s[i].fourcc, "mp4v", 4)) {
+ fti[n++] = (fti_t){ 0, 1, i, 7, 6, 1 };
+ fti[n++] = (fti_t){ 0, 2, i, 7, 6, 1 };
+ consume[i] = e_consume_mpeg4;
+ } else if (s[i].fourcc_len == 4 && !strncmp(s[i].fourcc, "h264", 4)) {
+ consume[i] = e_consume_h264;
+ } else {
+ consume[i] = e_consume_video;
+ }
+ break;
+ case NUT_AUDIO_CLASS:
+ fti[n++] = (fti_t){NUT_FLAG_KEY| FLAG_SIZE_MSB, 1, i, 1, 0, 1 };
+ fti[n++] = (fti_t){NUT_FLAG_KEY|FLAG_CODED_PTS|FLAG_SIZE_MSB, 0, i, 1, 0, 1 };
+ if (s[i].fourcc_len == 4 && !strncmp(s[i].fourcc, "mp3 ", 4)) {
+ int j, a[] = {288,336,384,480,576,672,768,960};
+ for (j = 0; j < sizeof a/sizeof*a; j++)
+ fti[n++] = (fti_t){ NUT_FLAG_KEY, 1, i, a[j]+1, a[j], 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_SIZE_MSB, 1, i, 4, 0, 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_SIZE_MSB, 1, i, 4, 2, 1 };
+ } else if (s[i].fourcc_len == 4 && !strncmp(s[i].fourcc, "vrbs", 4)) {
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_SIZE_MSB, 2, i, 1, 0, 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_SIZE_MSB, 9, i, 1, 0, 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_SIZE_MSB, 23, i, 1, 0, 1 };
+ fti[n++] = (fti_t){ NUT_FLAG_KEY|FLAG_SIZE_MSB, 16, i, 6, 0, 6 }; m+=5;
+ consume[i] = e_consume_vorbis;
+ }
+ break;
+ case NUT_SUBTITLE_CLASS:
+ fti[n++] = (fti_t){NUT_FLAG_KEY|FLAG_SIZE_MSB|FLAG_CODED_PTS, 0, i, 5, 0, 5 }; m+=4;
+ fti[n++] = (fti_t){NUT_FLAG_KEY|NUT_FLAG_EOR| FLAG_CODED_PTS, 0, i, 1, 0, 1 };
+ break;
+ case NUT_USERDATA_CLASS:
+ fti[n++] = (fti_t){NUT_FLAG_KEY|FLAG_SIZE_MSB|FLAG_CODED_PTS, 0, i, 1, 0, 1 };
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB|FLAG_CODED_PTS, 0, i, 1, 0, 1 };
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ for (i = 0; i < stream_count; i++) if (consume[i]) tot_con++;
+ if (tot_con) for (i = 0; i < stream_count; i++) {
+ int al = (254 - (n+m))/tot_con; // 256 - 'N' - 0xFF invalids
+ switch (consume[i]) {
+ case e_consume_none:
+ break;
+ case e_consume_mpeg4: {
+ int al1 = al*35/100;
+ int al2 = al*45/100;
+ int al3 = al-al1-al2;
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, 1, i, al1, 0, al1 }; m+=al1-1;
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, 2, i, al2, 0, al2 }; m+=al2-1;
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, -1, i, al3, 0, al3 }; m+=al3-1;
+ break;
+ }
+ case e_consume_h264: {
+ int al1 = al*35/100;
+ int al2 = al*35/100;
+ int al3 = al*20/100;
+ int al4 = al-al1-al2-al3;
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, 1, i, al1, 0, al1 }; m+=al1-1;
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, 2, i, al2, 0, al2 }; m+=al2-1;
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, -1, i, al3, 0, al3 }; m+=al3-1;
+ fti[n++] = (fti_t){ FLAG_CODED_PTS|FLAG_SIZE_MSB, 0, i, al4, 0, al4 }; m+=al4-1;
+ break;
+ }
+ case e_consume_video:
+ fti[n++] = (fti_t){ FLAG_SIZE_MSB, 1, i, al, 0, al }; m+=al-1;
+ break;
+ case e_consume_vorbis: {
+ int al1 = al*70/100;
+ int al2 = al-al1;
+ al1 /= 2; al2 /= 2;
+ fti[n++] = (fti_t){ NUT_FLAG_KEY, 16, i,240+al1,240-al1, al1*2 }; m+=al1*2-1;
+ fti[n++] = (fti_t){ NUT_FLAG_KEY, 2, i, 65+al2, 65-al2, al2*2 }; m+=al2*2-1;
+ break;
+ }
+ }
+ }
+ i = 255-n-m;
+ fti[n++] = (fti_t){ /*invalid 0xFF*/ FLAG_INVALID, 0, 0, i, 0, i };
+ // the final framecode. flag, pts, stream, mul, size, count
+ fti[n++] = (fti_t){ -1 };
+}
Modified: trunk/libnut/libnut.h
==============================================================================
--- trunk/libnut/libnut.h (original)
+++ trunk/libnut/libnut.h Fri Nov 17 17:52:04 2006
@@ -155,6 +155,9 @@
void nut_write_frame_reorder(nut_context_t * nut, const nut_packet_t * p, const uint8_t * buf);
void nut_muxer_uninit_reorder(nut_context_t * nut);
+/** generate framecode table input for the muxer. the fallback for the muxer if the muxer option is NULL */
+void nut_framecode_generate(const nut_stream_header_t s[], nut_frame_table_input_t fti[256]);
+
// Demuxer
/** Just inits stuff, can never fail, except memory error... */
Modified: trunk/libnut/muxer.c
==============================================================================
--- trunk/libnut/muxer.c (original)
+++ trunk/libnut/muxer.c Fri Nov 17 17:52:04 2006
@@ -523,6 +523,7 @@
nut_context_t * nut_muxer_init(const nut_muxer_opts_t * mopts, const nut_stream_header_t s[], const nut_info_packet_t info[]) {
nut_context_t * nut;
+ nut_frame_table_input_t * fti = mopts->fti, mfti[256];
int i, n;
// TODO check that all input is valid
@@ -549,24 +550,31 @@
if (nut->max_distance > 65536) nut->max_distance = 65536;
+ if (!fti) {
+ nut_framecode_generate(s, mfti);
+ fti = mfti;
+ }
+ fprintf(stderr, "/""/ { %4s, %3s, %6s, %3s, %4s, %5s },\n", "flag", "pts", "stream", "mul", "size", "count");
for (n=i=0; i < 256; n++) {
int j;
- assert(mopts->fti[n].flag != -1);
+ assert(fti[n].flag != -1);
- for(j = 0; j < mopts->fti[n].count && i < 256; j++, i++) {
+ fprintf(stderr, " { %4d, %3d, %6d, %3d, %4d, %5d },\n", fti[n].flag, fti[n].pts, fti[n].stream, fti[n].mul, fti[n].size, fti[n].count);
+ for(j = 0; j < fti[n].count && i < 256; j++, i++) {
if (i == 'N') {
nut->ft[i].flags = FLAG_INVALID;
j--;
continue;
}
- nut->ft[i].flags = mopts->fti[n].flag;
- nut->ft[i].pts_delta = mopts->fti[n].pts;
- nut->ft[i].mul = mopts->fti[n].mul;
- nut->ft[i].stream = mopts->fti[n].stream;
- nut->ft[i].lsb = mopts->fti[n].size + j;
+ nut->ft[i].flags = fti[n].flag;
+ nut->ft[i].pts_delta = fti[n].pts;
+ nut->ft[i].mul = fti[n].mul;
+ nut->ft[i].stream = fti[n].stream;
+ nut->ft[i].lsb = fti[n].size + j;
}
}
- assert(mopts->fti[n].flag == -1);
+ fprintf(stderr, " { %4d, %3d, %6d, %3d, %4d, %5d },\n", fti[n].flag, fti[n].pts, fti[n].stream, fti[n].mul, fti[n].size, fti[n].count);
+ assert(fti[n].flag == -1);
nut->sync_overhead = 0;
Modified: trunk/nututils/nutmerge.c
==============================================================================
--- trunk/nututils/nutmerge.c (original)
+++ trunk/nututils/nutmerge.c Fri Nov 17 17:52:04 2006
@@ -29,34 +29,6 @@
NULL
};
-nut_frame_table_input_t ft_default[] = {
- // There must be atleast this safety net:
- //{ 4128, 0, 0, 1, 0, 1 },
- //{ flag, pts, stream, mul, size, count }
- { 8192, 0, 0, 1, 0, 1 }, // invalid 0x00
- { 56, 0, 0, 1, 0, 1 }, // safety net non key frame
- { 57, 0, 0, 1, 0, 1 }, // safety net key frame
- { 4128, 0, 0, 1, 0, 1 }, // one more safety net
- { 27, 0, 0, 1, 0, 1 }, // EOR frame
- { 1, 1, 1, 337, 336, 1 }, // used 82427 times
- { 1, 1, 1, 385, 384, 1 }, // used 56044 times
- { 0, 2, 0, 7, 6, 1 }, // used 20993 times
- { 0, 1, 0, 7, 6, 1 }, // used 10398 times
- { 1, 1, 1, 481, 480, 1 }, // used 3527 times
- { 1, 1, 1, 289, 288, 1 }, // used 2042 times
- { 1, 1, 1, 577, 576, 1 }, // used 1480 times
- { 1, 1, 1, 673, 672, 1 }, // used 862 times
- { 1, 1, 1, 769, 768, 1 }, // used 433 times
- { 1, 1, 1, 961, 960, 1 }, // used 191 times
- { 32, 2, 0, 101, 0, 101 }, // "1.2.0" => 14187
- { 32, -1, 0, 40, 0, 40 }, // "1.-1.0" => 5707
- { 32, 1, 0, 81, 0, 81 }, // "1.1.0" => 11159
- { 33, 1, 0, 11, 0, 11 }, // "1.1.1" => 1409
- { 105, 0, 0, 6, 0, 6 }, // checksum for video
- { 8192, 0, 0, 1, 0, 1 }, // invalid 0xFF
- { -1, 0, 0, 0, 0, 0 }, // end
-};
-
void push_packet(stream_t * stream, packet_t * p) {
if (stream->npackets == stream->packets_alloc) {
stream->packets_alloc += 20;
@@ -128,7 +100,7 @@
mopts.output = (nut_output_stream_t){ .priv = out, .write = NULL };
mopts.write_index = 1;
mopts.realtime_stream = 0;
- mopts.fti = ft_default;
+ mopts.fti = NULL;
mopts.max_distance = 32768;
mopts.alloc.malloc = NULL;
nut = nut_muxer_init(&mopts, nut_stream, NULL);
More information about the NUT-devel
mailing list