Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Stuff
Sunday, March 25th, 2007 at 5:23:21pm UTC 

  1. Index: apps/plugins/mpegplayer/mpegplayer.c
  2. ===================================================================
  3. --- apps/plugins/mpegplayer/mpegplayer.c        (revision 12900)
  4. +++ apps/plugins/mpegplayer/mpegplayer.c        (working copy)
  5. @@ -172,8 +172,11 @@
  6.     uint8_t* curr_packet;        /* Current stream packet beginning */
  7.     uint8_t* curr_packet_end;    /* Current stream packet end */
  8.  
  9. -   uint8_t* next_packet;        /* Next stream packet beginning */   
  10. -
  11. +   uint8_t* prev_packet;        /* Previous stream packet beginning */
  12. +   uint8_t* next_packet;        /* Next stream packet beginning */
  13. +
  14. +   size_t guard_bytes;          /* Number of bytes in guardbuf used */
  15. +   size_t buffer_remaining;     /* How much data is left in the buffer */
  16.     int id;
  17.  } Stream;
  18.  
  19. @@ -184,6 +187,8 @@
  20.     on the ipod (reason unknown)
  21.  */
  22.  static uint8_t *disk_buf, *disk_buf_end;
  23. +static uint8_t *disk_buf_tail IBSS_ATTR;
  24. +static size_t buffer_size IBSS_ATTR;
  25.  
  26.  /* Events */
  27.  static struct event_queue msg_queue IBSS_ATTR;
  28. @@ -211,8 +216,17 @@
  29.  /* TODO: Can we reduce the PCM buffer size? */
  30.  #define PCMBUFFER_SIZE (512*1024)
  31.  #define AUDIOBUFFER_SIZE (32*1024)
  32. +#ifdef SIMULATOR
  33. +/* Make this large, so the main buffer is small - for testing buffering */
  34.  #define LIBMPEG2BUFFER_SIZE (2*1024*1024)
  35. +#else
  36. +#define LIBMPEG2BUFFER_SIZE (2*1024*1024)
  37. +#endif
  38.  
  39. +/* TODO: Is 32KB enough?  */
  40. +#define MPEG_GUARDBUF_SIZE (32*1024)
  41. +#define MPEG_LOW_WATERMARK (1024*1024)
  42. +
  43.  static void button_loop(void)
  44.  {
  45.      bool result;
  46. @@ -344,7 +358,7 @@
  47.  uint8_t system_header_start_code [4] = { 0x00, 0x00, 0x01, 0xbb };
  48.  
  49.  /* This function demux the streams and give the next stream data pointer */
  50. -static void get_next_data( Stream* str )
  51. +static void get_next_data( Stream* str)
  52.  {
  53.      uint8_t *p;
  54.      uint8_t *header;
  55. @@ -358,6 +372,7 @@
  56.          /* What does this do? */
  57.          while( (p = disk_buf) == NULL )
  58.          {
  59. +DEBUGF("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  60.              rb->lcd_putsxy(0,LCD_HEIGHT-10,"FREEZE!");
  61.              rb->lcd_update();
  62.              rb->sleep(100);
  63. @@ -365,11 +380,17 @@
  64.      } else {
  65.          p = str->curr_packet_end;
  66.      }
  67. -   
  68. +
  69.      for( ;; )
  70.      {
  71.          int length, bytes;
  72.          
  73. +            if( p >= disk_buf_end )
  74. +            {
  75. +                p = disk_buf + (p - disk_buf_end);
  76. +DEBUGF("**** Wrapping pointer for %02x\n",str->id);
  77. +            }
  78. +
  79.          /* Pack header, skip it */
  80.          if( rb->memcmp (p, pack_start_code, sizeof (pack_start_code)) == 0 )
  81.          {
  82. @@ -397,6 +418,11 @@
  83.              /*rb->splash( 30, "System header" );*/
  84.          }
  85.          
  86. +            if( p > disk_buf_end )
  87. +            {
  88. +                DEBUGF("REBUFFERING NEEDED... 3\n");
  89. +            }
  90. +
  91.          /* Packet header, parse it */
  92.          if( rb->memcmp (p, packet_start_code_prefix, sizeof (packet_start_code_prefix)) != 0 )
  93.          {
  94. @@ -428,6 +454,11 @@
  95.              continue;
  96.          }
  97.          
  98. +            if( p > disk_buf_end )
  99. +            {
  100. +                DEBUGF("REBUFFERING NEEDED... 4\n");
  101. +            }
  102. +
  103.          /* Ok, it's our packet */
  104.          str->curr_packet_end = p + length+6;   
  105.          header = p;
  106. @@ -461,6 +492,7 @@
  107.                  if (length > 23)
  108.                  {
  109.                      rb->splash( 30, "Too much stuffing" );
  110. +DEBUGF("Too much stuffing" );
  111.                      break;
  112.                  }
  113.              }
  114. @@ -488,20 +520,37 @@
  115.                      mpeg2_tag_picture (mpeg2dec, pts, dts);
  116.              }
  117.          }
  118. +
  119.          p += length;
  120.          bytes = 6 + (header[4] << 8) + header[5] - length;
  121.          if (bytes > 0) {
  122. -            /*str->curr_packet_end = p+bytes;*/
  123. +            str->curr_packet_end = p+bytes;
  124. +            //DEBUGF("prev = %d, curr = %d\n",str->prev_packet,str->curr_packet);
  125. +
  126. +            if (str->curr_packet != NULL) {
  127. +                if (str->curr_packet < str->prev_packet) {
  128. +                    str->buffer_remaining -= (disk_buf_end - str->prev_packet) + (str->curr_packet - disk_buf);
  129. +                    str->buffer_remaining -= str->guard_bytes;
  130. +                    str->guard_bytes = 0;
  131. +                } else {
  132. +                    str->buffer_remaining -= (str->curr_packet - str->prev_packet);
  133. +                }
  134. +
  135. +                str->prev_packet = str->curr_packet;
  136. +            }
  137. +
  138. +            DEBUGF("audio = %d, video = %d\n",audio_str.buffer_remaining,video_str.buffer_remaining);
  139. +
  140.              str->curr_packet = p;
  141. -            return;
  142. +
  143. +            if( str->curr_packet_end > disk_buf_end )
  144. +            {
  145. +                str->guard_bytes = str->curr_packet_end-disk_buf_end;
  146. +                rb->memcpy(disk_buf_end,disk_buf,str->guard_bytes);
  147. +                DEBUGF("memcpy to guard buffer - curr_packet=%d, curr_packet_end=%d, disk_buf_end=%d\n",str->curr_packet,str->curr_packet_end,disk_buf_end);
  148. +            }
  149. +            return ;
  150.          }
  151. -       
  152. -        if( str->curr_packet_end > disk_buf_end )
  153. -        {
  154. -            /* We should ask for buffering here */
  155. -            str->curr_packet_end = str->curr_packet = NULL;
  156. -            return;
  157. -        }
  158.                  
  159.          break;
  160.      }   
  161. @@ -575,7 +624,7 @@
  162.             goto done;
  163.          }
  164.  
  165. -        if (n < 1000) {  /* TODO: What is the maximum size of an MPEG audio frame? */
  166. +        if (n < 1500) {  /* TODO: What is the maximum size of an MPEG audio frame? */
  167.              get_next_data( &audio_str );
  168.              if (audio_str.curr_packet == NULL) {
  169.                  /* Wait for audio to finish */
  170. @@ -585,6 +634,7 @@
  171.              len = audio_str.curr_packet_end - audio_str.curr_packet;
  172.              if (n + len > mpa_buffer_size) {
  173.                  rb->splash( 30, "Audio buffer overflow" );
  174. +                DEBUGF("Audio buffer overflow" );
  175.                  audiostatus=STREAM_DONE;
  176.                  /* Wait to be killed */
  177.                  for (;;) { rb->sleep(HZ); }
  178. @@ -599,6 +649,7 @@
  179.          }
  180.  
  181.          if (mad_frame_decode(&frame, &stream)) {
  182. +            DEBUGF("Audio stream error - %d\n",stream.error);
  183.              if (stream.error == MAD_FLAG_INCOMPLETE
  184.                  || stream.error == MAD_ERROR_BUFLEN) {
  185.                  /* This makes the codec support partially corrupted files */
  186. @@ -620,6 +671,7 @@
  187.                  continue;
  188.              } else {
  189.                  /* Some other unrecoverable error */
  190. +                DEBUGF("Unrecoverable error\n");
  191.                  break;
  192.              }
  193.              break;
  194. @@ -636,6 +688,7 @@
  195.              n -= len;
  196.          } else {
  197.              /* What to do here? */
  198. +            DEBUGF("/* What to do here? */\n");
  199.              goto done;
  200.          }
  201.  #if 0
  202. @@ -714,6 +767,7 @@
  203.  done:
  204.      rb->pcm_play_stop();
  205.      audiostatus=STREAM_DONE;
  206. +DEBUGF("Audio thread ended." );
  207.  
  208.      for (;;) { 
  209.          button_loop();
  210. @@ -723,7 +777,7 @@
  211.  
  212.  /* End of libmad stuff */
  213.  
  214. -static uint64_t eta IBSS_ATTR;
  215. +static int64_t eta IBSS_ATTR;
  216.  
  217.  /* TODO: Running in the main thread, libmad needs 8.25KB of stack.
  218.     The codec thread uses a 9KB stack.  So we can probable reduce this a
  219. @@ -745,9 +799,9 @@
  220.      int skipcount = 0;
  221.      int frame = 0;
  222.      int lasttick;
  223. -    unsigned int eta2;
  224. -    unsigned int s;
  225. -    int fps;
  226. +    int64_t eta2;
  227. +    int64_t s;
  228. +    int64_t fps;
  229.  
  230.      rb->sleep(HZ/5);
  231.      mpeg2dec = mpeg2_init ();
  232. @@ -820,6 +874,7 @@
  233.  
  234.                  /*  Convert eta (in 27MHz ticks) into audio samples */
  235.                  eta2 =(eta * 44100) / 27000000;
  236. +
  237.                  s = samplesplayed - (rb->pcm_get_bytes_waiting() >> 2);
  238.                  if (settings.limitfps) {
  239.                      if (eta2 > s) {
  240. @@ -841,9 +896,11 @@
  241.                  /* Calculate fps */
  242.                  frame++;
  243.                  if (settings.showfps && (*rb->current_tick-lasttick>=HZ)) {
  244. -                    fps=(frame*441000)/s;
  245. +                    fps=frame;
  246. +                    fps*=441000;
  247. +                    fps/=s;
  248.                      rb->snprintf(str,sizeof(str),"%d.%d %d %d %d",
  249. -                                 (fps/10),fps%10,skipped,s,eta2);
  250. +                                 (int)(fps/10),(int)(fps%10),skipped,(int)s,(int)eta2);
  251.                      rb->lcd_putsxy(0,0,str);
  252.                      rb->lcd_update_rect(0,0,LCD_WIDTH,8);
  253.          
  254. @@ -870,7 +927,11 @@
  255.      int audiosize;
  256.      int in_file;
  257.      uint8_t* buffer;
  258. -    size_t buffer_size;
  259. +    size_t audio_remaining, video_remaining;
  260. +    size_t bytes_to_read;
  261. +    size_t file_remaining;
  262. +    size_t n;
  263. +    size_t disk_buf_len;
  264.  
  265.      /* We define this here so it is on the main stack (in IRAM) */
  266.      mad_fixed_t mad_frame_overlap[2][32][18];       /* 4608 bytes */
  267. @@ -898,7 +959,13 @@
  268.      /* Grab most of the buffer for the compressed video - leave some for
  269.         PCM audio data and some for libmpeg2 malloc use. */
  270.      buffer_size = audiosize - (PCMBUFFER_SIZE+AUDIOBUFFER_SIZE+LIBMPEG2BUFFER_SIZE);
  271. +
  272.      DEBUGF("audiosize=%d, buffer_size=%ld\n",audiosize,buffer_size);
  273. +    buffer_size &= ~(0x7ff);  /* Round buffer down to nearest 2KB */
  274. +#ifdef SIMULATOR
  275. +    buffer_size = 28096512;
  276. +#endif
  277. +    DEBUGF("audiosize=%d, buffer_size=%ld\n",audiosize,buffer_size);
  278.      buffer = mpeg2_malloc(buffer_size,-1);
  279.  
  280.      if (buffer == NULL)
  281. @@ -961,11 +1028,23 @@
  282.  
  283.      eta = 0;
  284.  
  285. -    rb->splash(0, "Buffering...");
  286. +    file_remaining = rb->filesize(in_file);
  287. +    disk_buf_end = buffer + buffer_size-MPEG_GUARDBUF_SIZE;
  288.  
  289. -    disk_buf_end = buffer + rb->read (in_file, buffer, buffer_size);
  290. +    disk_buf_len = rb->read (in_file, buffer, MPEG_LOW_WATERMARK);
  291. +
  292. +    DEBUGF("Initial Buffering - %d bytes\n",disk_buf_len);
  293.      disk_buf = buffer;
  294. +    disk_buf_tail = buffer+disk_buf_len;
  295. +    file_remaining -= disk_buf_len;
  296.  
  297. +    video_str.guard_bytes = audio_str.guard_bytes = 0;
  298. +    video_str.prev_packet = disk_buf;
  299. +    audio_str.prev_packet = disk_buf;
  300. +    video_str.buffer_remaining = disk_buf_len;
  301. +    audio_str.buffer_remaining = disk_buf_len;
  302. +
  303. +    //DEBUGF("START: video = %d, audio = %d\n",audio_str.buffer_remaining,video_str.buffer_remaining);
  304.      rb->lcd_setfont(FONT_SYSFIXED);
  305.  
  306.      audiostatus = STREAM_BUFFERING;
  307. @@ -991,6 +1070,32 @@
  308.  
  309.      /* Wait until both threads have finished their work */
  310.      while ((audiostatus != STREAM_DONE) || (videostatus != STREAM_DONE)) {
  311. +        audio_remaining = audio_str.buffer_remaining;
  312. +        video_remaining = video_str.buffer_remaining;
  313. +        if (MIN(audio_remaining,video_remaining) < MPEG_LOW_WATERMARK) {
  314. +
  315. +            // TODO: Add mutex when updating the A/V buffer_remaining variables.
  316. +            bytes_to_read = buffer_size - MPEG_GUARDBUF_SIZE - MAX(audio_remaining,video_remaining);
  317. +
  318. +            bytes_to_read = MIN(bytes_to_read,(size_t)(disk_buf_end-disk_buf_tail));
  319. +
  320. +            while (( bytes_to_read > 0) && (file_remaining > 0)) {
  321. +                DEBUGF("Reading %d bytes\n",MIN(128*1024,bytes_to_read));
  322. +                n = rb->read(in_file, disk_buf_tail, MIN(128*1024,bytes_to_read));
  323. +                DEBUGF("Read %d bytes, bytes_to_read = %d, file_remaining=%d\n",n,bytes_to_read,file_remaining);
  324. +                DEBUGF("buffer = %d, disk_buf_tail = %d\n",buffer, disk_buf_tail);
  325. +                bytes_to_read -= n;
  326. +                file_remaining -= n;
  327. +                audio_str.buffer_remaining += n;
  328. +                video_str.buffer_remaining += n;
  329. +                disk_buf_tail += n;
  330. +                rb->yield();
  331. +            }
  332. +
  333. +            if (disk_buf_tail == disk_buf_end)
  334. +                disk_buf_tail = buffer;
  335. +
  336. +        }
  337.          rb->sleep(HZ/10);
  338.      }
  339.  

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.

comments powered by Disqus
worth-right