-static inline uint64_t get_vb_trace(ByteIOContext *bc, char *file, char *func, int line){
- uint64_t v= get_vb(bc);
-
- printf("get_vb %5lld / %llX in %s %s:%d\n", v, v, file, func, line);
- return v;
-}
-#define get_v(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_vb(bc) get_vb_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#endif
-
-
-static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int calculate_checksum)
-{
- int64_t start, size;
- start= url_ftell(bc) - 8;
-
- init_checksum(bc, calculate_checksum ? update_adler32 : NULL, 0);
-
- size= get_v(bc);
-
- nut->packet_start[2] = start;
- nut->written_packet_size= size;
-
- return size;
-}
-
-static int check_checksum(ByteIOContext *bc){
- unsigned long checksum= get_checksum(bc);
- return checksum != get_be32(bc);
-}
-
-/**
- *
- */
-static int get_length(uint64_t val){
- int i;
-
- for (i=7; val>>i; i+=7);
-
- return i;
-}
-
-static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){
- uint64_t state=0;
-
- if(pos >= 0)
- url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream isnt seekable, but that shouldnt matter, as in this case we simply start where we are currently
-
- while(!url_feof(bc)){
- state= (state<<8) | get_byte(bc);
- if((state>>56) != 'N')
- continue;
- switch(state){
- case MAIN_STARTCODE:
- case STREAM_STARTCODE:
- case KEYFRAME_STARTCODE:
- case INFO_STARTCODE:
- case INDEX_STARTCODE:
- return state;
- }
- }
-
- return 0;
-}
-
-/**
- * find the given startcode.
- * @param code the startcode
- * @param pos the start position of the search, or -1 if the current position
- * @returns the position of the startcode or -1 if not found
- */
-static int64_t find_startcode(ByteIOContext *bc, uint64_t code, int64_t pos){
- for(;;){
- uint64_t startcode= find_any_startcode(bc, pos);
- if(startcode == code)
- return url_ftell(bc) - 8;
- else if(startcode == 0)
- return -1;
- pos=-1;
- }
-}
-
-#ifdef CONFIG_ENCODERS
-
-static void put_v(ByteIOContext *bc, uint64_t val)
-{
- int i;
-
-//av_log(NULL, AV_LOG_DEBUG, "put_v()= %lld\n", val);
- val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
- i= get_length(val);
-
- for (i-=7; i>0; i-=7){
- put_byte(bc, 0x80 | (val>>i));
- }
-
- put_byte(bc, val&0x7f);
-}
-
-/**
- * stores a string as vb.
- */
-static void put_str(ByteIOContext *bc, const char *string){
- int len= strlen(string);
-
- put_v(bc, len);
- put_buffer(bc, string, len);
-}
-
-static void put_s(ByteIOContext *bc, uint64_t val){
- if (val<=0) put_v(bc, -2*val );
- else put_v(bc, 2*val-1);
-}
-
-static void put_vb(ByteIOContext *bc, uint64_t val){
- int i;
-
- for (i=8; val>>i; i+=8);
-
- put_v(bc, i>>3);
- for(i-=8; i>=0; i-=8)
- put_byte(bc, (val>>i)&0xFF);
-}
-
-#ifdef TRACE
-static inline void put_v_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){
- printf("get_v %5lld / %llX in %s %s:%d\n", v, v, file, func, line);
-
- put_v(bc, v);
-}
-
-static inline void put_s_trace(ByteIOContext *bc, int64_t v, char *file, char *func, int line){
- printf("get_s %5lld / %llX in %s %s:%d\n", v, v, file, func, line);
-
- put_s(bc, v);
-}
-
-static inline void put_vb_trace(ByteIOContext *bc, uint64_t v, char *file, char *func, int line){
- printf("get_vb %5lld / %llX in %s %s:%d\n", v, v, file, func, line);
-
- put_vb(bc, v);
-}
-#define put_v(bc, v) put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define put_vb(bc, v) put_vb_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#endif
-
-static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size, int calculate_checksum)
-{
- put_flush_packet(bc);
- nut->packet_start[2]+= nut->written_packet_size;
- assert(url_ftell(bc) - 8 == nut->packet_start[2]);
- nut->written_packet_size = max_size;
-
- if(calculate_checksum)
- init_checksum(bc, update_adler32, 0);
-
- /* packet header */
- put_v(bc, nut->written_packet_size); /* forward ptr */
-
- return 0;
-}
-
-static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size, int calculate_checksum){
- int64_t start= nut->packet_start[2];
- int64_t cur= url_ftell(bc);
- int size= cur - start + additional_size;
-
- if(calculate_checksum)
- size += 4;
-
- if(size != nut->written_packet_size){
- int i;
-
- assert( size <= nut->written_packet_size );
-
- url_fseek(bc, start + 8, SEEK_SET);
- for(i=get_length(size); i < get_length(nut->written_packet_size); i+=7)
- put_byte(bc, 0x80);
- put_v(bc, size);
-
- url_fseek(bc, cur, SEEK_SET);
- nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ
-
- if(calculate_checksum)
- put_be32(bc, get_checksum(bc));
- }
-
- return 0;
-}
-
-static int nut_write_header(AVFormatContext *s)
-{
- NUTContext *nut = s->priv_data;
- ByteIOContext *bc = &s->pb;
- AVCodecContext *codec;
- int i, j, tmp_time, tmp_flags,tmp_stream, tmp_mul, tmp_size, tmp_fields;
-
- nut->avf= s;
-
- nut->stream =
- av_mallocz(sizeof(StreamContext)*s->nb_streams);
-
-
- put_buffer(bc, ID_STRING, strlen(ID_STRING));
- put_byte(bc, 0);
- nut->packet_start[2]= url_ftell(bc);
-
- /* main header */
- put_be64(bc, MAIN_STARTCODE);
- put_packetheader(nut, bc, 120+5*256, 1);
- put_v(bc, 2); /* version */
- put_v(bc, s->nb_streams);
- put_v(bc, MAX_DISTANCE);
- put_v(bc, MAX_SHORT_DISTANCE);
-
- put_v(bc, nut->rate_num=1);
- put_v(bc, nut->rate_den=2);
- put_v(bc, nut->short_startcode=0x4EFE79);
-
- build_frame_code(s);
- assert(nut->frame_code['N'].flags == FLAG_INVALID);
-
- tmp_time= tmp_flags= tmp_stream= tmp_mul= tmp_size= /*tmp_res=*/ INT_MAX;
- for(i=0; i<256;){
- tmp_fields=0;
- tmp_size= 0;
- if(tmp_time != nut->frame_code[i].timestamp_delta) tmp_fields=1;
- if(tmp_mul != nut->frame_code[i].size_mul ) tmp_fields=2;
- if(tmp_stream != nut->frame_code[i].stream_id_plus1) tmp_fields=3;
- if(tmp_size != nut->frame_code[i].size_lsb ) tmp_fields=4;
-// if(tmp_res != nut->frame_code[i].res ) tmp_fields=5;
-
- tmp_time = nut->frame_code[i].timestamp_delta;
- tmp_flags = nut->frame_code[i].flags;
- tmp_stream= nut->frame_code[i].stream_id_plus1;
- tmp_mul = nut->frame_code[i].size_mul;
- tmp_size = nut->frame_code[i].size_lsb;
-// tmp_res = nut->frame_code[i].res;
-
- for(j=0; i<256; j++,i++){
- if(nut->frame_code[i].timestamp_delta != tmp_time ) break;
- if(nut->frame_code[i].flags != tmp_flags ) break;
- if(nut->frame_code[i].stream_id_plus1 != tmp_stream) break;
- if(nut->frame_code[i].size_mul != tmp_mul ) break;
- if(nut->frame_code[i].size_lsb != tmp_size+j) break;
-// if(nut->frame_code[i].res != tmp_res ) break;
- }
- if(j != tmp_mul - tmp_size) tmp_fields=6;
-
- put_v(bc, tmp_flags);
- put_v(bc, tmp_fields);
- if(tmp_fields>0) put_s(bc, tmp_time);
- if(tmp_fields>1) put_v(bc, tmp_mul);
- if(tmp_fields>2) put_v(bc, tmp_stream);
- if(tmp_fields>3) put_v(bc, tmp_size);
- if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/);
- if(tmp_fields>5) put_v(bc, j);
- }
-
- update_packetheader(nut, bc, 0, 1);
-
- /* stream headers */
- for (i = 0; i < s->nb_streams; i++)
- {
- int nom, denom, gcd;
-
- codec = &s->streams[i]->codec;
-
- put_be64(bc, STREAM_STARTCODE);
- put_packetheader(nut, bc, 120 + codec->extradata_size, 1);
- put_v(bc, i /*s->streams[i]->index*/);
- put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);
- if (codec->codec_tag)
- put_vb(bc, codec->codec_tag);
- else if (codec->codec_type == CODEC_TYPE_VIDEO)
- {
- put_vb(bc, codec_get_bmp_tag(codec->codec_id));
- }
- else if (codec->codec_type == CODEC_TYPE_AUDIO)
- {
- put_vb(bc, codec_get_wav_tag(codec->codec_id));
- }
- else
- put_vb(bc, 0);
-
- if (codec->codec_type == CODEC_TYPE_VIDEO)
- {
- nom = codec->frame_rate;
- denom = codec->frame_rate_base;
- }
- else
- {
- nom = codec->sample_rate;
- if(codec->frame_size>0)
- denom= codec->frame_size;
- else
- denom= 1; //unlucky
- }
- gcd= ff_gcd(nom, denom);
- nom /= gcd;
- denom /= gcd;
- nut->stream[i].rate_num= nom;
- nut->stream[i].rate_den= denom;
- av_set_pts_info(s->streams[i], 60, denom, nom);
-
- put_v(bc, codec->bit_rate);
- put_vb(bc, 0); /* no language code */
- put_v(bc, nom);
- put_v(bc, denom);
- if(nom / denom < 1000)
- nut->stream[i].msb_timestamp_shift = 7;
- else
- nut->stream[i].msb_timestamp_shift = 14;
- put_v(bc, nut->stream[i].msb_timestamp_shift);
- put_v(bc, codec->has_b_frames);
- put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
-
- if(codec->extradata_size){
- put_v(bc, 1);
- put_v(bc, codec->extradata_size);
- put_buffer(bc, codec->extradata, codec->extradata_size);
- }
- put_v(bc, 0); /* end of codec specific headers */
-
- switch(codec->codec_type)
- {
- case CODEC_TYPE_AUDIO:
- put_v(bc, codec->sample_rate);
- put_v(bc, 1);
- put_v(bc, codec->channels);
- break;
- case CODEC_TYPE_VIDEO:
- put_v(bc, codec->width);
- put_v(bc, codec->height);
- put_v(bc, codec->sample_aspect_ratio.num);
- put_v(bc, codec->sample_aspect_ratio.den);
- put_v(bc, 0); /* csp type -- unknown */
- break;
- default:
- break;
- }
- update_packetheader(nut, bc, 0, 1);
- }
-
- /* info header */
- put_be64(bc, INFO_STARTCODE);
- put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+
- strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1);
- if (s->author[0])
- {
- put_v(bc, 9); /* type */
- put_str(bc, s->author);
- }
- if (s->title[0])
- {
- put_v(bc, 10); /* type */
- put_str(bc, s->title);
- }
- if (s->comment[0])
- {
- put_v(bc, 11); /* type */
- put_str(bc, s->comment);
- }
- if (s->copyright[0])
- {
- put_v(bc, 12); /* type */
- put_str(bc, s->copyright);
- }
- /* encoder */
- if(!(s->streams[0]->codec.flags & CODEC_FLAG_BITEXACT)){
- put_v(bc, 13); /* type */
- put_str(bc, LIBAVFORMAT_IDENT);
- }
-
- put_v(bc, 0); /* eof info */
- update_packetheader(nut, bc, 0, 1);
-
- put_flush_packet(bc);
-
- return 0;
-}
-
-static int64_t lsb2full(StreamContext *stream, int64_t lsb){
- int64_t mask = (1<<stream->msb_timestamp_shift)-1;