You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1339 lines
37KB

  1. /*
  2. * "NUT" Container Format muxer and demuxer (DRAFT-200403??)
  3. * Copyright (c) 2003 Alex Beregszaszi
  4. * Copyright (c) 2004 Michael Niedermayer
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. *
  20. * NUT DRAFT can be found in MPlayer CVS at DOCS/tech/mpcf.txt
  21. *
  22. * AND http://people.fsn.hu/~alex/nut/ (TeX, pdf, ps, dvi, ..)
  23. *
  24. */
  25. /*
  26. * TODO:
  27. * - index writing
  28. * - index packet reading support
  29. */
  30. //#define DEBUG 1
  31. #include <limits.h>
  32. #include "avformat.h"
  33. #include "mpegaudio.h"
  34. #include "avi.h"
  35. #undef NDEBUG
  36. #include <assert.h>
  37. //from /dev/random
  38. #define MAIN_STARTCODE (0x7A561F5F04ADULL + (((uint64_t)('N'<<8) + 'M')<<48))
  39. #define STREAM_STARTCODE (0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48))
  40. #define KEYFRAME_STARTCODE (0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48))
  41. #define INDEX_STARTCODE (0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48))
  42. #define INFO_STARTCODE (0xAB68B596BA78ULL + (((uint64_t)('N'<<8) + 'I')<<48))
  43. #define MAX_DISTANCE (1024*16-1)
  44. #define MAX_SHORT_DISTANCE (1024*4-1)
  45. #define MAX_PTS_LRU 3
  46. #define FLAG_DATA_SIZE 4
  47. #define FLAG_PTS 3
  48. #define FLAG_KEY_FRAME 8
  49. typedef struct {
  50. uint8_t flags;
  51. uint8_t stream_id_plus1;
  52. uint16_t size_mul;
  53. uint16_t size_lsb;
  54. } FrameCode;
  55. typedef struct {
  56. int last_key_frame;
  57. int msb_timestamp_shift;
  58. int rate_num;
  59. int rate_den;
  60. int64_t last_pts;
  61. int lru_pts_delta[MAX_PTS_LRU];
  62. int initial_pts_predictor[MAX_PTS_LRU];
  63. int64_t last_sync_pos; ///<pos of last 1/2 type frame
  64. int decode_delay;
  65. } StreamContext;
  66. typedef struct {
  67. AVFormatContext *avf;
  68. int written_packet_size;
  69. int64_t packet_start[3]; //0-> startcode less, 1-> short startcode 2-> long startcodes
  70. FrameCode frame_code[256];
  71. int stream_count;
  72. uint64_t next_startcode; ///< stores the next startcode if it has alraedy been parsed but the stream isnt seekable
  73. StreamContext *stream;
  74. int max_distance;
  75. } NUTContext;
  76. static char *info_table[][2]={
  77. {NULL , NULL }, // end
  78. {NULL , NULL },
  79. {NULL , "UTF8"},
  80. {NULL , "v"},
  81. {NULL , "s"},
  82. {"StreamId" , "v"},
  83. {"SegmentId" , "v"},
  84. {"StartTimestamp" , "v"},
  85. {"EndTimestamp" , "v"},
  86. {"Author" , "UTF8"},
  87. {"Title" , "UTF8"},
  88. {"Description" , "UTF8"},
  89. {"Copyright" , "UTF8"},
  90. {"Encoder" , "UTF8"},
  91. {"Keyword" , "UTF8"},
  92. {"Cover" , "JPEG"},
  93. {"Cover" , "PNG"},
  94. };
  95. static void update_lru(int *lru, int current, int count){
  96. int i;
  97. for(i=0; i<count-1; i++){
  98. if(lru[i] == current)
  99. break;
  100. }
  101. for(; i; i--){
  102. lru[i]= lru[i-1];
  103. }
  104. lru[0]= current;
  105. }
  106. static void update(NUTContext *nut, int stream_index, int64_t frame_start, int frame_type, int frame_code, int key_frame, int size, int64_t pts){
  107. StreamContext *stream= &nut->stream[stream_index];
  108. stream->last_key_frame= key_frame;
  109. nut->packet_start[ frame_type ]= frame_start;
  110. if(stream->last_pts != AV_NOPTS_VALUE){
  111. assert(frame_type < 2);
  112. update_lru(stream->lru_pts_delta, pts - stream->last_pts, 3);
  113. }
  114. stream->last_pts= pts;
  115. }
  116. static void reset(AVFormatContext *s/*, int frame_type*/){
  117. NUTContext *nut = s->priv_data;
  118. int i;
  119. for(i=0; i<s->nb_streams; i++){
  120. StreamContext *stream= &nut->stream[i];
  121. stream->last_key_frame= 1;
  122. stream->last_pts= AV_NOPTS_VALUE;
  123. memcpy(stream->lru_pts_delta, stream->initial_pts_predictor, sizeof(int)*MAX_PTS_LRU);
  124. }
  125. }
  126. static void build_frame_code(AVFormatContext *s){
  127. NUTContext *nut = s->priv_data;
  128. int key_frame, index, pred, stream_id, full_pts;
  129. int start=0;
  130. int end= 255;
  131. int keyframe_0_esc= s->nb_streams > 2;
  132. if(keyframe_0_esc){
  133. /* keyframe = 0 escape */
  134. FrameCode *ft= &nut->frame_code[start];
  135. ft->flags= FLAG_DATA_SIZE | FLAG_PTS;
  136. ft->stream_id_plus1= 0;
  137. ft->size_mul=1;
  138. start++;
  139. }
  140. for(stream_id= 0; stream_id<s->nb_streams; stream_id++){
  141. int start2= start + (end-start)*stream_id / s->nb_streams;
  142. int end2 = start + (end-start)*(stream_id+1) / s->nb_streams;
  143. AVCodecContext *codec = &s->streams[stream_id]->codec;
  144. int is_audio= codec->codec_type == CODEC_TYPE_AUDIO;
  145. int intra_only= /*codec->intra_only || */is_audio;
  146. int pred_count;
  147. for(key_frame=0; key_frame<2; key_frame++){
  148. if(intra_only && keyframe_0_esc && key_frame==0)
  149. continue;
  150. {
  151. FrameCode *ft= &nut->frame_code[start2];
  152. ft->flags= FLAG_KEY_FRAME*key_frame;
  153. ft->flags|= FLAG_DATA_SIZE | FLAG_PTS;
  154. ft->stream_id_plus1= stream_id + 1;
  155. ft->size_mul=1;
  156. start2++;
  157. }
  158. }
  159. key_frame= intra_only;
  160. #if 1
  161. if(is_audio){
  162. int frame_bytes= codec->frame_size*(int64_t)codec->bit_rate / (8*codec->sample_rate);
  163. for(full_pts=0; full_pts<2; full_pts++){
  164. for(pred=0; pred<2; pred++){
  165. FrameCode *ft= &nut->frame_code[start2];
  166. ft->flags= FLAG_KEY_FRAME*key_frame + FLAG_PTS*full_pts;
  167. ft->stream_id_plus1= stream_id + 1;
  168. ft->size_mul=frame_bytes + 2;
  169. ft->size_lsb=frame_bytes + pred;
  170. start2++;
  171. av_log(NULL, AV_LOG_DEBUG, "%d\n", frame_bytes + pred);
  172. }
  173. }
  174. }else{
  175. FrameCode *ft= &nut->frame_code[start2];
  176. ft->flags= FLAG_KEY_FRAME | FLAG_DATA_SIZE;
  177. ft->stream_id_plus1= stream_id + 1;
  178. ft->size_mul=1;
  179. start2++;
  180. }
  181. #endif
  182. pred_count= 2 + codec->has_b_frames + (codec->codec_id == CODEC_ID_VORBIS);
  183. for(pred=0; pred<pred_count; pred++){
  184. int start3= start2 + (end2-start2)*pred / pred_count;
  185. int end3 = start2 + (end2-start2)*(pred+1) / pred_count;
  186. for(index=start3; index<end3; index++){
  187. FrameCode *ft= &nut->frame_code[index];
  188. ft->flags= FLAG_KEY_FRAME*key_frame + pred*4;
  189. ft->flags|= FLAG_DATA_SIZE;
  190. ft->stream_id_plus1= stream_id + 1;
  191. //FIXME use single byte size and pred from last
  192. ft->size_mul= end3-start3;
  193. ft->size_lsb= index - start3;
  194. }
  195. nut->stream[stream_id].initial_pts_predictor[pred]= pred+1;
  196. }
  197. }
  198. memmove(&nut->frame_code['N'+1], &nut->frame_code['N'], sizeof(FrameCode)*(255-'N'));
  199. nut->frame_code['N'].flags= 1;
  200. }
  201. static uint64_t get_v(ByteIOContext *bc)
  202. {
  203. uint64_t val = 0;
  204. for(;;)
  205. {
  206. int tmp = get_byte(bc);
  207. if (tmp&0x80)
  208. val= (val<<7) + tmp - 0x80;
  209. else{
  210. //av_log(NULL, AV_LOG_DEBUG, "get_v()= %lld\n", (val<<7) + tmp);
  211. return (val<<7) + tmp;
  212. }
  213. }
  214. return -1;
  215. }
  216. static int get_str(ByteIOContext *bc, char *string, int maxlen){
  217. int len= get_v(bc);
  218. if(len && maxlen)
  219. get_buffer(bc, string, FFMIN(len, maxlen));
  220. while(len > maxlen){
  221. get_byte(bc);
  222. len--;
  223. }
  224. if(maxlen)
  225. string[FFMIN(len, maxlen-1)]= 0;
  226. if(maxlen == len)
  227. return -1;
  228. else
  229. return 0;
  230. }
  231. static uint64_t get_vb(ByteIOContext *bc){
  232. uint64_t val=0;
  233. int i= get_v(bc);
  234. if(i>8)
  235. return UINT64_MAX;
  236. while(i--)
  237. val = (val<<8) + get_byte(bc);
  238. //av_log(NULL, AV_LOG_DEBUG, "get_vb()= %lld\n", val);
  239. return val;
  240. }
  241. static int get_packetheader(NUTContext *nut, ByteIOContext *bc, int calculate_checksum)
  242. {
  243. int64_t start, size;
  244. start= url_ftell(bc) - 8;
  245. init_checksum(bc, calculate_checksum ? update_adler32 : NULL, 0);
  246. size= get_v(bc);
  247. nut->packet_start[2] = start;
  248. nut->written_packet_size= size;
  249. return size;
  250. }
  251. static int check_checksum(ByteIOContext *bc){
  252. unsigned long checksum= get_checksum(bc);
  253. return checksum != get_be32(bc);
  254. }
  255. /**
  256. *
  257. */
  258. static int get_length(uint64_t val){
  259. int i;
  260. for (i=7; val>>i; i+=7);
  261. return i;
  262. }
  263. static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){
  264. uint64_t state=0;
  265. if(pos >= 0)
  266. 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
  267. while(!url_feof(bc)){
  268. state= (state<<8) | get_byte(bc);
  269. if((state>>56) != 'N')
  270. continue;
  271. switch(state){
  272. case MAIN_STARTCODE:
  273. case STREAM_STARTCODE:
  274. case KEYFRAME_STARTCODE:
  275. case INFO_STARTCODE:
  276. case INDEX_STARTCODE:
  277. return state;
  278. }
  279. }
  280. return 0;
  281. }
  282. /**
  283. * find the given startcode.
  284. * @param code the startcode
  285. * @param pos the start position of the search, or -1 if the current position
  286. * @returns the position of the startcode or -1 if not found
  287. */
  288. static int64_t find_startcode(ByteIOContext *bc, uint64_t code, int64_t pos){
  289. for(;;){
  290. uint64_t startcode= find_any_startcode(bc, pos);
  291. if(startcode == code)
  292. return url_ftell(bc) - 8;
  293. else if(startcode == 0)
  294. return -1;
  295. pos=-1;
  296. }
  297. }
  298. #ifdef CONFIG_ENCODERS
  299. static void put_v(ByteIOContext *bc, uint64_t val)
  300. {
  301. int i;
  302. //av_log(NULL, AV_LOG_DEBUG, "put_v()= %lld\n", val);
  303. val &= 0x7FFFFFFFFFFFFFFFULL; // FIXME can only encode upto 63 bits currently
  304. i= get_length(val);
  305. for (i-=7; i>0; i-=7){
  306. put_byte(bc, 0x80 | (val>>i));
  307. }
  308. put_byte(bc, val&0x7f);
  309. }
  310. /**
  311. * stores a string as vb.
  312. */
  313. static void put_str(ByteIOContext *bc, const char *string){
  314. int len= strlen(string);
  315. put_v(bc, len);
  316. put_buffer(bc, string, len);
  317. }
  318. static void put_vb(ByteIOContext *bc, uint64_t val){
  319. int i;
  320. for (i=8; val>>i; i+=8);
  321. put_v(bc, i>>3);
  322. for(i-=8; i>=0; i-=8)
  323. put_byte(bc, (val>>i)&0xFF);
  324. }
  325. static int put_packetheader(NUTContext *nut, ByteIOContext *bc, int max_size, int calculate_checksum)
  326. {
  327. put_flush_packet(bc);
  328. nut->packet_start[2]+= nut->written_packet_size;
  329. assert(url_ftell(bc) - 8 == nut->packet_start[2]);
  330. nut->written_packet_size = max_size;
  331. if(calculate_checksum)
  332. init_checksum(bc, update_adler32, 0);
  333. /* packet header */
  334. put_v(bc, nut->written_packet_size); /* forward ptr */
  335. return 0;
  336. }
  337. static int update_packetheader(NUTContext *nut, ByteIOContext *bc, int additional_size, int calculate_checksum){
  338. int64_t start= nut->packet_start[2];
  339. int64_t cur= url_ftell(bc);
  340. int size= cur - start + additional_size;
  341. if(calculate_checksum)
  342. size += 4;
  343. if(size != nut->written_packet_size){
  344. int i;
  345. assert( size <= nut->written_packet_size );
  346. url_fseek(bc, start + 8, SEEK_SET);
  347. for(i=get_length(size); i < get_length(nut->written_packet_size); i+=7)
  348. put_byte(bc, 0x80);
  349. put_v(bc, size);
  350. url_fseek(bc, cur, SEEK_SET);
  351. nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ
  352. if(calculate_checksum)
  353. put_be32(bc, get_checksum(bc));
  354. }
  355. return 0;
  356. }
  357. static int nut_write_header(AVFormatContext *s)
  358. {
  359. NUTContext *nut = s->priv_data;
  360. ByteIOContext *bc = &s->pb;
  361. AVCodecContext *codec;
  362. int i, j;
  363. nut->avf= s;
  364. nut->stream =
  365. av_mallocz(sizeof(StreamContext)*s->nb_streams);
  366. av_set_pts_info(s, 60, 1, AV_TIME_BASE);
  367. /* main header */
  368. put_be64(bc, MAIN_STARTCODE);
  369. put_packetheader(nut, bc, 120+5*256, 1);
  370. put_v(bc, 2); /* version */
  371. put_v(bc, s->nb_streams);
  372. put_v(bc, MAX_DISTANCE);
  373. build_frame_code(s);
  374. assert(nut->frame_code['N'].flags == 1);
  375. for(i=0; i<256;){
  376. int tmp_flags = nut->frame_code[i].flags;
  377. int tmp_stream= nut->frame_code[i].stream_id_plus1;
  378. int tmp_mul = nut->frame_code[i].size_mul;
  379. int tmp_size = nut->frame_code[i].size_lsb;
  380. put_v(bc, tmp_flags);
  381. put_v(bc, tmp_stream);
  382. put_v(bc, tmp_mul);
  383. put_v(bc, tmp_size);
  384. for(j=0; i<256; j++,i++){
  385. if(nut->frame_code[i].flags != tmp_flags ) break;
  386. if(nut->frame_code[i].stream_id_plus1 != tmp_stream) break;
  387. if(nut->frame_code[i].size_mul != tmp_mul ) break;
  388. if(nut->frame_code[i].size_lsb != tmp_size ) break;
  389. if(++tmp_size >= tmp_mul){
  390. tmp_size=0;
  391. tmp_stream++;
  392. }
  393. }
  394. put_v(bc, j);
  395. }
  396. update_packetheader(nut, bc, 0, 1);
  397. /* stream headers */
  398. for (i = 0; i < s->nb_streams; i++)
  399. {
  400. int nom, denom, gcd;
  401. codec = &s->streams[i]->codec;
  402. put_be64(bc, STREAM_STARTCODE);
  403. put_packetheader(nut, bc, 120 + codec->extradata_size, 1);
  404. put_v(bc, i /*s->streams[i]->index*/);
  405. put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);
  406. if (codec->codec_tag)
  407. put_vb(bc, codec->codec_tag);
  408. else if (codec->codec_type == CODEC_TYPE_VIDEO)
  409. {
  410. put_vb(bc, codec_get_bmp_tag(codec->codec_id));
  411. }
  412. else if (codec->codec_type == CODEC_TYPE_AUDIO)
  413. {
  414. put_vb(bc, codec_get_wav_tag(codec->codec_id));
  415. }
  416. else
  417. put_vb(bc, 0);
  418. if (codec->codec_type == CODEC_TYPE_VIDEO)
  419. {
  420. nom = codec->frame_rate;
  421. denom = codec->frame_rate_base;
  422. }
  423. else
  424. {
  425. nom = codec->sample_rate;
  426. if(codec->frame_size>0)
  427. denom= codec->frame_size;
  428. else
  429. denom= 1; //unlucky
  430. }
  431. gcd= ff_gcd(nom, denom);
  432. nom /= gcd;
  433. denom /= gcd;
  434. nut->stream[i].rate_num= nom;
  435. nut->stream[i].rate_den= denom;
  436. put_v(bc, codec->bit_rate);
  437. put_vb(bc, 0); /* no language code */
  438. put_v(bc, nom);
  439. put_v(bc, denom);
  440. if(nom / denom < 1000)
  441. nut->stream[i].msb_timestamp_shift = 7;
  442. else
  443. nut->stream[i].msb_timestamp_shift = 14;
  444. put_v(bc, nut->stream[i].msb_timestamp_shift);
  445. for(j=0; j<3; j++)
  446. put_v(bc, nut->stream[i].initial_pts_predictor[j]);
  447. put_v(bc, codec->has_b_frames);
  448. put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */
  449. if(codec->extradata_size){
  450. put_v(bc, 1);
  451. put_v(bc, codec->extradata_size);
  452. put_buffer(bc, codec->extradata, codec->extradata_size);
  453. }
  454. put_v(bc, 0); /* end of codec specific headers */
  455. switch(codec->codec_type)
  456. {
  457. case CODEC_TYPE_AUDIO:
  458. put_v(bc, codec->sample_rate);
  459. put_v(bc, 1);
  460. put_v(bc, codec->channels);
  461. break;
  462. case CODEC_TYPE_VIDEO:
  463. put_v(bc, codec->width);
  464. put_v(bc, codec->height);
  465. put_v(bc, codec->sample_aspect_ratio.num);
  466. put_v(bc, codec->sample_aspect_ratio.den);
  467. put_v(bc, 0); /* csp type -- unknown */
  468. break;
  469. default:
  470. break;
  471. }
  472. update_packetheader(nut, bc, 0, 1);
  473. }
  474. /* info header */
  475. put_be64(bc, INFO_STARTCODE);
  476. put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+
  477. strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1);
  478. if (s->author[0])
  479. {
  480. put_v(bc, 9); /* type */
  481. put_str(bc, s->author);
  482. }
  483. if (s->title[0])
  484. {
  485. put_v(bc, 10); /* type */
  486. put_str(bc, s->title);
  487. }
  488. if (s->comment[0])
  489. {
  490. put_v(bc, 11); /* type */
  491. put_str(bc, s->comment);
  492. }
  493. if (s->copyright[0])
  494. {
  495. put_v(bc, 12); /* type */
  496. put_str(bc, s->copyright);
  497. }
  498. /* encoder */
  499. if(!(s->streams[0]->codec.flags & CODEC_FLAG_BITEXACT)){
  500. put_v(bc, 13); /* type */
  501. put_str(bc, LIBAVFORMAT_IDENT);
  502. }
  503. put_v(bc, 0); /* eof info */
  504. update_packetheader(nut, bc, 0, 1);
  505. put_flush_packet(bc);
  506. return 0;
  507. }
  508. static int64_t lsb2full(StreamContext *stream, int64_t lsb){
  509. int64_t mask = (1<<stream->msb_timestamp_shift)-1;
  510. int64_t delta= stream->last_pts - mask/2;
  511. return ((lsb - delta)&mask) + delta;
  512. }
  513. static int nut_write_packet(AVFormatContext *s, int stream_index,
  514. const uint8_t *buf, int size, int64_t pts)
  515. {
  516. NUTContext *nut = s->priv_data;
  517. StreamContext *stream= &nut->stream[stream_index];
  518. ByteIOContext *bc = &s->pb;
  519. int key_frame = 0, full_pts=0;
  520. AVCodecContext *enc;
  521. int64_t coded_pts;
  522. int frame_type, best_length, frame_code, flags, i, size_mul, size_lsb;
  523. const int64_t frame_start= url_ftell(bc);
  524. if (stream_index > s->nb_streams)
  525. return 1;
  526. pts= (av_rescale(pts, stream->rate_num, stream->rate_den) + AV_TIME_BASE/2) / AV_TIME_BASE;
  527. enc = &s->streams[stream_index]->codec;
  528. key_frame = enc->coded_frame->key_frame;
  529. if(enc->coded_frame->pts != AV_NOPTS_VALUE)
  530. pts= (av_rescale(enc->coded_frame->pts, stream->rate_num, stream->rate_den) + AV_TIME_BASE/2) / AV_TIME_BASE; //FIXME XXX HACK
  531. frame_type=0;
  532. if(frame_start + size + 20 - FFMAX(nut->packet_start[1], nut->packet_start[2]) > MAX_DISTANCE)
  533. frame_type=2;
  534. if(key_frame && !stream->last_key_frame)
  535. frame_type=2;
  536. if(frame_type>1)
  537. reset(s);
  538. if(stream->last_pts == AV_NOPTS_VALUE)
  539. full_pts=1;
  540. else{
  541. coded_pts = pts & ((1<<stream->msb_timestamp_shift)-1);
  542. if(lsb2full(stream, coded_pts) != pts)
  543. full_pts=1;
  544. }
  545. if(full_pts)
  546. coded_pts= pts + (1<<stream->msb_timestamp_shift);
  547. best_length=INT_MAX;
  548. frame_code= -1;
  549. for(i=0; i<256; i++){
  550. int stream_id_plus1= nut->frame_code[i].stream_id_plus1;
  551. int fc_key_frame;
  552. int length=0;
  553. size_mul= nut->frame_code[i].size_mul;
  554. size_lsb= nut->frame_code[i].size_lsb;
  555. flags= nut->frame_code[i].flags;
  556. assert(size_mul > size_lsb);
  557. if(stream_id_plus1 == 0) length+= get_length(stream_index);
  558. else if(stream_id_plus1 - 1 != stream_index)
  559. continue;
  560. fc_key_frame= !!(flags & FLAG_KEY_FRAME);
  561. assert(key_frame==0 || key_frame==1);
  562. if(fc_key_frame != key_frame)
  563. continue;
  564. if(flags & FLAG_DATA_SIZE){
  565. if(size % size_mul != size_lsb)
  566. continue;
  567. length += get_length(size / size_mul);
  568. }else if(size != size_lsb)
  569. continue;
  570. if(full_pts && (flags & FLAG_PTS) != FLAG_PTS)
  571. continue;
  572. if(flags&FLAG_PTS){
  573. length += get_length(coded_pts);
  574. }else{
  575. int delta= stream->lru_pts_delta[flags & FLAG_PTS];
  576. if(delta != pts - stream->last_pts)
  577. continue;
  578. assert(frame_type < 2);
  579. }
  580. if(length < best_length){
  581. best_length= length;
  582. frame_code=i;
  583. }
  584. // av_log(s, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d %d %d\n", key_frame, frame_type, full_pts, size, stream_index, flags, size_mul, size_lsb, stream_id_plus1, length);
  585. }
  586. assert(frame_code != -1);
  587. flags= nut->frame_code[frame_code].flags;
  588. size_mul= nut->frame_code[frame_code].size_mul;
  589. size_lsb= nut->frame_code[frame_code].size_lsb;
  590. #if 0
  591. best_length /= 7;
  592. best_length ++; //frame_code
  593. if(frame_type==2){
  594. best_length += 8; // startcode
  595. }
  596. av_log(s, AV_LOG_DEBUG, "kf:%d ft:%d pt:%d fc:%2X len:%2d size:%d stream:%d flag:%d mul:%d lsb:%d s+1:%d pts_delta:%d pts:%lld\n", key_frame, frame_type, full_pts ? 2 : ((flags & FLAG_PTS) == FLAG_PTS ? 1 : 0), frame_code, best_length, size, stream_index, flags, size_mul, size_lsb, nut->frame_code[frame_code].stream_id_plus1,(int)(pts - stream->last_pts), pts);
  597. // av_log(s, AV_LOG_DEBUG, "%d %d %d\n", stream->lru_pts_delta[0], stream->lru_pts_delta[1], stream->lru_pts_delta[2]);
  598. #endif
  599. if (frame_type==2)
  600. put_be64(bc, KEYFRAME_STARTCODE);
  601. assert(frame_type != 1); //short startcode not implemented yet
  602. put_byte(bc, frame_code);
  603. if(nut->frame_code[frame_code].stream_id_plus1 == 0)
  604. put_v(bc, stream_index);
  605. if ((flags & FLAG_PTS) == FLAG_PTS){
  606. put_v(bc, coded_pts);
  607. }
  608. if(flags & FLAG_DATA_SIZE)
  609. put_v(bc, size / size_mul);
  610. if(size > MAX_DISTANCE){
  611. assert(frame_type > 1);
  612. }
  613. put_buffer(bc, buf, size);
  614. update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts);
  615. return 0;
  616. }
  617. static int nut_write_trailer(AVFormatContext *s)
  618. {
  619. NUTContext *nut = s->priv_data;
  620. ByteIOContext *bc = &s->pb;
  621. #if 0
  622. int i;
  623. /* WRITE INDEX */
  624. for (i = 0; s->nb_streams; i++)
  625. {
  626. put_be64(bc, INDEX_STARTCODE);
  627. put_packetheader(nut, bc, 64, 1);
  628. put_v(bc, s->streams[i]->id);
  629. put_v(bc, ...);
  630. update_packetheader(nut, bc, 0, 1);
  631. }
  632. #endif
  633. put_flush_packet(bc);
  634. av_freep(&nut->stream);
  635. return 0;
  636. }
  637. #endif //CONFIG_ENCODERS
  638. static int nut_probe(AVProbeData *p)
  639. {
  640. int i;
  641. uint64_t code= 0xff;
  642. for (i = 0; i < p->buf_size; i++) {
  643. code = (code << 8) | p->buf[i];
  644. if (code == MAIN_STARTCODE)
  645. return AVPROBE_SCORE_MAX;
  646. }
  647. return 0;
  648. }
  649. static int decode_main_header(NUTContext *nut){
  650. AVFormatContext *s= nut->avf;
  651. ByteIOContext *bc = &s->pb;
  652. uint64_t tmp;
  653. int i, j;
  654. get_packetheader(nut, bc, 1);
  655. tmp = get_v(bc);
  656. if (tmp != 2){
  657. av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp);
  658. return -1;
  659. }
  660. nut->stream_count = get_v(bc);
  661. nut->max_distance = get_v(bc);
  662. for(i=0; i<256;){
  663. int tmp_flags = get_v(bc);
  664. int tmp_stream= get_v(bc);
  665. int tmp_mul = get_v(bc);
  666. int tmp_size = get_v(bc);
  667. int count = get_v(bc);
  668. if(count == 0 || i+count > 256){
  669. av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i);
  670. return -1;
  671. }
  672. for(j=0; j<count; j++,i++){
  673. if(tmp_stream > nut->stream_count + 1){
  674. av_log(s, AV_LOG_ERROR, "illegal stream number\n");
  675. return -1;
  676. }
  677. nut->frame_code[i].flags = tmp_flags ;
  678. nut->frame_code[i].stream_id_plus1 = tmp_stream;
  679. nut->frame_code[i].size_mul = tmp_mul ;
  680. nut->frame_code[i].size_lsb = tmp_size ;
  681. if(++tmp_size >= tmp_mul){
  682. tmp_size=0;
  683. tmp_stream++;
  684. }
  685. }
  686. }
  687. if(nut->frame_code['N'].flags != 1){
  688. av_log(s, AV_LOG_ERROR, "illegal frame_code table\n");
  689. return -1;
  690. }
  691. if(check_checksum(bc)){
  692. av_log(s, AV_LOG_ERROR, "Main header checksum missmatch\n");
  693. return -1;
  694. }
  695. return 0;
  696. }
  697. static int decode_stream_header(NUTContext *nut){
  698. AVFormatContext *s= nut->avf;
  699. ByteIOContext *bc = &s->pb;
  700. int class, nom, denom, stream_id, i;
  701. uint64_t tmp;
  702. AVStream *st;
  703. get_packetheader(nut, bc, 1);
  704. stream_id= get_v(bc);
  705. if(stream_id >= nut->stream_count || s->streams[stream_id])
  706. return -1;
  707. st = av_new_stream(s, stream_id);
  708. if (!st)
  709. return AVERROR_NOMEM;
  710. class = get_v(bc);
  711. tmp = get_vb(bc);
  712. st->codec.codec_tag= tmp;
  713. switch(class)
  714. {
  715. case 0:
  716. st->codec.codec_type = CODEC_TYPE_VIDEO;
  717. st->codec.codec_id = codec_get_bmp_id(tmp);
  718. if (st->codec.codec_id == CODEC_ID_NONE)
  719. av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
  720. break;
  721. case 32:
  722. st->codec.codec_type = CODEC_TYPE_AUDIO;
  723. st->codec.codec_id = codec_get_wav_id(tmp);
  724. if (st->codec.codec_id == CODEC_ID_NONE)
  725. av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");
  726. break;
  727. default:
  728. av_log(s, AV_LOG_ERROR, "Unknown stream class (%d)\n", class);
  729. return -1;
  730. }
  731. s->bit_rate += get_v(bc);
  732. get_vb(bc); /* language code */
  733. nom = get_v(bc);
  734. denom = get_v(bc);
  735. nut->stream[stream_id].msb_timestamp_shift = get_v(bc);
  736. for(i=0; i<3; i++)
  737. nut->stream[stream_id].initial_pts_predictor[i]= get_v(bc);
  738. nut->stream[stream_id].decode_delay= get_v(bc);
  739. get_byte(bc); /* flags */
  740. /* codec specific data headers */
  741. while(get_v(bc) != 0){
  742. st->codec.extradata_size= get_v(bc);
  743. st->codec.extradata= av_mallocz(st->codec.extradata_size);
  744. get_buffer(bc, st->codec.extradata, st->codec.extradata_size);
  745. // url_fskip(bc, get_v(bc));
  746. }
  747. if (class == 0) /* VIDEO */
  748. {
  749. st->codec.width = get_v(bc);
  750. st->codec.height = get_v(bc);
  751. st->codec.sample_aspect_ratio.num= get_v(bc);
  752. st->codec.sample_aspect_ratio.den= get_v(bc);
  753. get_v(bc); /* csp type */
  754. st->codec.frame_rate = nom;
  755. st->codec.frame_rate_base = denom;
  756. }
  757. if (class == 32) /* AUDIO */
  758. {
  759. st->codec.sample_rate = get_v(bc);
  760. get_v(bc); // samplerate_den
  761. st->codec.channels = get_v(bc);
  762. }
  763. if(check_checksum(bc)){
  764. av_log(s, AV_LOG_ERROR, "Stream header %d checksum missmatch\n", stream_id);
  765. return -1;
  766. }
  767. nut->stream[stream_id].rate_num= nom;
  768. nut->stream[stream_id].rate_den= denom;
  769. return 0;
  770. }
  771. static int decode_info_header(NUTContext *nut){
  772. AVFormatContext *s= nut->avf;
  773. ByteIOContext *bc = &s->pb;
  774. get_packetheader(nut, bc, 1);
  775. for(;;){
  776. int id= get_v(bc);
  777. char *name, *type, custom_name[256], custom_type[256];
  778. if(!id)
  779. break;
  780. else if(id >= sizeof(info_table)/sizeof(info_table[0])){
  781. av_log(s, AV_LOG_ERROR, "info id is too large %d %d\n", id, sizeof(info_table)/sizeof(info_table[0]));
  782. return -1;
  783. }
  784. type= info_table[id][1];
  785. name= info_table[id][0];
  786. //av_log(s, AV_LOG_DEBUG, "%d %s %s\n", id, type, name);
  787. if(!type){
  788. get_str(bc, custom_type, sizeof(custom_type));
  789. type= custom_type;
  790. }
  791. if(!name){
  792. get_str(bc, custom_name, sizeof(custom_name));
  793. name= custom_name;
  794. }
  795. if(!strcmp(type, "v")){
  796. int value= get_v(bc);
  797. }else{
  798. if(!strcmp(name, "Author"))
  799. get_str(bc, s->author, sizeof(s->author));
  800. else if(!strcmp(name, "Title"))
  801. get_str(bc, s->title, sizeof(s->title));
  802. else if(!strcmp(name, "Copyright"))
  803. get_str(bc, s->copyright, sizeof(s->copyright));
  804. else if(!strcmp(name, "Description"))
  805. get_str(bc, s->comment, sizeof(s->comment));
  806. else
  807. get_str(bc, NULL, 0);
  808. }
  809. }
  810. if(check_checksum(bc)){
  811. av_log(s, AV_LOG_ERROR, "Info header checksum missmatch\n");
  812. return -1;
  813. }
  814. return 0;
  815. }
  816. static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
  817. {
  818. NUTContext *nut = s->priv_data;
  819. ByteIOContext *bc = &s->pb;
  820. int64_t pos;
  821. int inited_stream_count;
  822. nut->avf= s;
  823. av_set_pts_info(s, 60, 1, AV_TIME_BASE);
  824. /* main header */
  825. pos=0;
  826. for(;;){
  827. pos= find_startcode(bc, MAIN_STARTCODE, pos)+1;
  828. if (pos<0){
  829. av_log(s, AV_LOG_ERROR, "no main startcode found\n");
  830. return -1;
  831. }
  832. if(decode_main_header(nut) >= 0)
  833. break;
  834. }
  835. s->bit_rate = 0;
  836. nut->stream = av_malloc(sizeof(StreamContext)*nut->stream_count);
  837. /* stream headers */
  838. pos=0;
  839. for(inited_stream_count=0; inited_stream_count < nut->stream_count;){
  840. pos= find_startcode(bc, STREAM_STARTCODE, pos)+1;
  841. if (pos<0){
  842. av_log(s, AV_LOG_ERROR, "not all stream headers found\n");
  843. return -1;
  844. }
  845. if(decode_stream_header(nut) >= 0)
  846. inited_stream_count++;
  847. }
  848. /* info headers */
  849. pos=0;
  850. for(;;){
  851. uint64_t startcode= find_any_startcode(bc, pos);
  852. pos= url_ftell(bc);
  853. if(startcode==0){
  854. av_log(s, AV_LOG_ERROR, "EOF before video frames\n");
  855. return -1;
  856. }else if(startcode == KEYFRAME_STARTCODE){
  857. nut->next_startcode= startcode;
  858. break;
  859. }else if(startcode != INFO_STARTCODE){
  860. continue;
  861. }
  862. decode_info_header(nut);
  863. }
  864. return 0;
  865. }
  866. static int decode_frame_header(NUTContext *nut, int *key_frame_ret, int64_t *pts_ret, int *stream_id_ret, int frame_code, int frame_type){
  867. AVFormatContext *s= nut->avf;
  868. StreamContext *stream;
  869. ByteIOContext *bc = &s->pb;
  870. int size, flags, size_mul, size_lsb, stream_id;
  871. int64_t pts = 0;
  872. const int prefix_len= frame_type == 2 ? 8+1 : 1;
  873. const int64_t frame_start= url_ftell(bc) - prefix_len;
  874. if(frame_type < 2 && frame_start - nut->packet_start[2] > nut->max_distance){
  875. av_log(s, AV_LOG_ERROR, "last frame must have been damaged\n");
  876. return -1;
  877. }
  878. if(frame_type)
  879. nut->packet_start[ frame_type ]= frame_start; //otherwise 1 goto 1 may happen
  880. flags= nut->frame_code[frame_code].flags;
  881. size_mul= nut->frame_code[frame_code].size_mul;
  882. size_lsb= nut->frame_code[frame_code].size_lsb;
  883. stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1;
  884. if(frame_type == 2)
  885. reset(s);
  886. if(stream_id==-1)
  887. stream_id= get_v(bc);
  888. if(stream_id >= s->nb_streams){
  889. av_log(s, AV_LOG_ERROR, "illegal stream_id\n");
  890. return -1;
  891. }
  892. stream= &nut->stream[stream_id];
  893. // av_log(s, AV_LOG_DEBUG, "ft:%d ppts:%d %d %d\n", frame_type, stream->lru_pts_delta[0], stream->lru_pts_delta[1], stream->lru_pts_delta[2]);
  894. *key_frame_ret= !!(flags & FLAG_KEY_FRAME);
  895. if((flags & FLAG_PTS) == FLAG_PTS){
  896. int64_t mask = (1<<stream->msb_timestamp_shift)-1;
  897. pts= get_v(bc);
  898. if(pts > mask){
  899. pts -= mask+1;
  900. }else{
  901. if(stream->last_pts == AV_NOPTS_VALUE){
  902. av_log(s, AV_LOG_ERROR, "no reference pts available\n");
  903. return -1;
  904. }
  905. pts= lsb2full(stream, pts);
  906. }
  907. }else{
  908. if(stream->last_pts == AV_NOPTS_VALUE){
  909. av_log(s, AV_LOG_ERROR, "no reference pts available\n");
  910. return -1;
  911. }
  912. pts= stream->last_pts + stream->lru_pts_delta[flags&FLAG_PTS];
  913. }
  914. if(*key_frame_ret){
  915. int64_t av_pts= pts * AV_TIME_BASE * stream->rate_den / stream->rate_num;
  916. // av_log(s, AV_LOG_DEBUG, "stream:%d start:%lld pts:%lld length:%lld\n",stream_id, frame_start, av_pts, frame_start - nut->stream[stream_id].last_sync_pos);
  917. av_add_index_entry(
  918. s->streams[stream_id],
  919. frame_start,
  920. av_pts,
  921. frame_start - nut->stream[stream_id].last_sync_pos,
  922. AVINDEX_KEYFRAME);
  923. nut->stream[stream_id].last_sync_pos= frame_start;
  924. // assert(nut->packet_start == frame_start);
  925. }
  926. assert(size_mul > size_lsb);
  927. size= size_lsb;
  928. if(flags & FLAG_DATA_SIZE)
  929. size+= size_mul*get_v(bc);
  930. //av_log(s, AV_LOG_DEBUG, "fs:%lld fc:%d ft:%d kf:%d pts:%lld size:%d\n", frame_start, frame_code, frame_type, key_frame, pts, size);
  931. if(frame_type==0 && url_ftell(bc) - nut->packet_start[2] + size > nut->max_distance){
  932. av_log(s, AV_LOG_ERROR, "frame size too large\n");
  933. return -1;
  934. }
  935. *stream_id_ret = stream_id;
  936. *pts_ret = pts * AV_TIME_BASE * stream->rate_den / stream->rate_num;
  937. update(nut, stream_id, frame_start, frame_type, frame_code, *key_frame_ret, size, pts);
  938. return size;
  939. }
  940. static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type){
  941. AVFormatContext *s= nut->avf;
  942. ByteIOContext *bc = &s->pb;
  943. int size, stream_id, key_frame;
  944. int64_t pts;
  945. size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type);
  946. if(size < 0)
  947. return -1;
  948. av_new_packet(pkt, size);
  949. get_buffer(bc, pkt->data, size);
  950. pkt->stream_index = stream_id;
  951. if (key_frame)
  952. pkt->flags |= PKT_FLAG_KEY;
  953. pkt->pts = pts;
  954. return 0;
  955. }
  956. static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
  957. {
  958. NUTContext *nut = s->priv_data;
  959. ByteIOContext *bc = &s->pb;
  960. int i, frame_code=0;
  961. for(;;){
  962. int frame_type= 0;
  963. uint64_t tmp= nut->next_startcode;
  964. nut->next_startcode=0;
  965. if (url_feof(bc))
  966. return -1;
  967. if(!tmp){
  968. frame_code = get_byte(bc);
  969. if(frame_code == 'N'){
  970. tmp= frame_code;
  971. for(i=1; i<8; i++)
  972. tmp = (tmp<<8) + get_byte(bc);
  973. }
  974. }
  975. switch(tmp){
  976. case MAIN_STARTCODE:
  977. case STREAM_STARTCODE:
  978. case INDEX_STARTCODE:
  979. get_packetheader(nut, bc, 0);
  980. url_fseek(bc, nut->written_packet_size + nut->packet_start[2], SEEK_SET);
  981. break;
  982. case INFO_STARTCODE:
  983. if(decode_info_header(nut)<0)
  984. goto resync;
  985. break;
  986. case KEYFRAME_STARTCODE:
  987. frame_type = 2;
  988. frame_code = get_byte(bc);
  989. case 0:
  990. if(decode_frame(nut, pkt, frame_code, frame_type)>=0)
  991. return 0;
  992. default:
  993. resync:
  994. av_log(s, AV_LOG_DEBUG, "syncing from %lld\n", nut->packet_start[2]+1);
  995. tmp= find_any_startcode(bc, nut->packet_start[2]+1);
  996. if(tmp==0)
  997. return -1;
  998. av_log(s, AV_LOG_DEBUG, "sync\n");
  999. nut->next_startcode= tmp;
  1000. }
  1001. }
  1002. }
  1003. static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){
  1004. NUTContext *nut = s->priv_data;
  1005. StreamContext *stream;
  1006. ByteIOContext *bc = &s->pb;
  1007. int64_t pos, pts;
  1008. uint64_t code;
  1009. int frame_code,step, stream_id, i,size, key_frame;
  1010. av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%lld,%lld)\n", stream_index, *pos_arg, pos_limit);
  1011. if(*pos_arg < 0)
  1012. return AV_NOPTS_VALUE;
  1013. pos= *pos_arg;
  1014. step= FFMIN(16*1024, pos);
  1015. do{
  1016. pos-= step;
  1017. code= find_any_startcode(bc, pos);
  1018. if(code && url_ftell(bc) - 8 <= *pos_arg)
  1019. break;
  1020. step= FFMIN(2*step, pos);
  1021. }while(step);
  1022. if(!code) //nothing found, not even after pos_arg
  1023. return AV_NOPTS_VALUE;
  1024. url_fseek(bc, -8, SEEK_CUR);
  1025. for(i=0; i<s->nb_streams; i++)
  1026. nut->stream[i].last_sync_pos= url_ftell(bc);
  1027. for(;;){
  1028. int frame_type=0;
  1029. int64_t pos= url_ftell(bc);
  1030. uint64_t tmp=0;
  1031. if(pos > pos_limit || url_feof(bc))
  1032. return AV_NOPTS_VALUE;
  1033. frame_code = get_byte(bc);
  1034. if(frame_code == 'N'){
  1035. tmp= frame_code;
  1036. for(i=1; i<8; i++)
  1037. tmp = (tmp<<8) + get_byte(bc);
  1038. }
  1039. //av_log(s, AV_LOG_DEBUG, "before switch %llX at=%lld\n", tmp, pos);
  1040. switch(tmp){
  1041. case MAIN_STARTCODE:
  1042. case STREAM_STARTCODE:
  1043. case INDEX_STARTCODE:
  1044. case INFO_STARTCODE:
  1045. get_packetheader(nut, bc, 0);
  1046. assert(nut->packet_start[2]==pos);
  1047. url_fseek(bc, nut->written_packet_size + pos, SEEK_SET);
  1048. break;
  1049. case KEYFRAME_STARTCODE:
  1050. frame_type=2;
  1051. frame_code = get_byte(bc);
  1052. case 0:
  1053. size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type);
  1054. if(size < 0)
  1055. goto resync;
  1056. stream= &nut->stream[stream_id];
  1057. if(stream_id != stream_index || !key_frame || pos < *pos_arg){
  1058. url_fseek(bc, size, SEEK_CUR);
  1059. break;
  1060. }
  1061. *pos_arg= pos;
  1062. return pts;
  1063. default:
  1064. resync:
  1065. av_log(s, AV_LOG_DEBUG, "syncing from %lld\n", nut->packet_start[2]+1);
  1066. if(!find_any_startcode(bc, nut->packet_start[2]+1))
  1067. return AV_NOPTS_VALUE;
  1068. url_fseek(bc, -8, SEEK_CUR);
  1069. }
  1070. }
  1071. return AV_NOPTS_VALUE;
  1072. }
  1073. static int nut_read_seek(AVFormatContext *s, int stream_index, int64_t target_ts){
  1074. // NUTContext *nut = s->priv_data;
  1075. int64_t pos;
  1076. if(av_seek_frame_binary(s, stream_index, target_ts) < 0)
  1077. return -1;
  1078. pos= url_ftell(&s->pb);
  1079. nut_read_timestamp(s, stream_index, &pos, pos-1);
  1080. return 0;
  1081. }
  1082. static int nut_read_close(AVFormatContext *s)
  1083. {
  1084. NUTContext *nut = s->priv_data;
  1085. int i;
  1086. for(i=0;i<s->nb_streams;i++) {
  1087. av_freep(&s->streams[i]->codec.extradata);
  1088. }
  1089. av_freep(&nut->stream);
  1090. return 0;
  1091. }
  1092. static AVInputFormat nut_iformat = {
  1093. "nut",
  1094. "nut format",
  1095. sizeof(NUTContext),
  1096. nut_probe,
  1097. nut_read_header,
  1098. nut_read_packet,
  1099. nut_read_close,
  1100. nut_read_seek,
  1101. nut_read_timestamp,
  1102. .extensions = "nut",
  1103. };
  1104. #ifdef CONFIG_ENCODERS
  1105. static AVOutputFormat nut_oformat = {
  1106. "nut",
  1107. "nut format",
  1108. "video/x-nut",
  1109. "nut",
  1110. sizeof(NUTContext),
  1111. #ifdef CONFIG_VORBIS
  1112. CODEC_ID_VORBIS,
  1113. #elif defined(CONFIG_MP3LAME)
  1114. CODEC_ID_MP3,
  1115. #else
  1116. CODEC_ID_MP2, /* AC3 needs liba52 decoder */
  1117. #endif
  1118. CODEC_ID_MPEG4,
  1119. nut_write_header,
  1120. nut_write_packet,
  1121. nut_write_trailer,
  1122. };
  1123. #endif //CONFIG_ENCODERS
  1124. int nut_init(void)
  1125. {
  1126. av_register_input_format(&nut_iformat);
  1127. #ifdef CONFIG_ENCODERS
  1128. av_register_output_format(&nut_oformat);
  1129. #endif //CONFIG_ENCODERS
  1130. return 0;
  1131. }