2012年5月29日 星期二

S3C6410 MFC H.264 mp4 player (Bug fix)

In the previous post, I implement an mp4 player.
There's a problem confuse me.
The start of video frame seems broken. Then after some time (maybe seconds) the video frame goes well.

Finally, I found a way to solve it.
Just to decode the first frame twice. Really strange but work. Also there's some minor fix included

https://docs.google.com/open?id=0Bx901QMLr9WlVE1ldHVCaERkRkk

Patch

--- /home/gigijoe/mp4player.c    2012-05-29 16:11:06.094007930 +0800
+++ mp4player.c    2012-05-29 16:17:55.073995127 +0800
@@ -176,8 +176,12 @@
     pp_param.dst_width              = pp_param.dst_full_width;
     pp_param.dst_height             = pp_param.dst_full_height;
     pp_param.dst_color_space        = FB0_COLOR_SPACE;
+#if 1
     pp_param.out_path               = DMA_ONESHOT;
-
+#else
+        pp_param.out_path           = FIFO_FREERUN;
+        pp_param.scan_mode            = PROGRESSIVE_MODE;
+#endif
     ioctl(pp_fd, S3C_PP_SET_PARAMS, &pp_param);
     printf("stream width %d, height %d\n", pp_param.src_full_width, pp_param.src_full_height);
 
@@ -193,7 +197,7 @@
       return -1;
     }
 
-    memset(fb_addr, 0, fb_size);
+    //memset(fb_addr, 0, fb_size);
 
     s3c_win_info_t osd_info_to_driver;
     osd_info_to_driver.Bpp          = FB0_BPP;      // RGB16
@@ -212,6 +216,13 @@
     initialize = 1;
 
     //return 0;
+/*
+* Decode first frame again to avoid problem ...
+*/
+    if(SsbSipH264DecodeExe(handle, len) != SSBSIP_H264_DEC_RET_OK)  {
+      printf("MFC Decoder Configuration Failed.\n");
+      return -1;
+    }
   }
 
   unsigned int pYUVBuf[2];
@@ -229,6 +240,12 @@
   ioctl(fb_fd, FBIOGET_FSCREENINFO, &lcd_info);
   pp_param.dst_buf_addr_phy = lcd_info.smem_start;                  // LCD frame buffer
   ioctl(pp_fd, S3C_PP_SET_DST_BUF_ADDR_PHY, &pp_param);
+
+  struct pollfd test_fd;
+  test_fd.fd = pp_fd;
+  test_fd.events = POLLOUT|POLLERR;
+  poll(&test_fd, 1, 3000);
+
   ioctl(pp_fd, S3C_PP_START);
 
   return 0;
@@ -342,12 +359,15 @@
   AVCodecContext *codecContext = is->codec;
 
   long long delay = (1000000 * is->r_frame_rate.den) / (is->r_frame_rate.num);
-
-#if 0
+#if 1
   i = 0;
 #endif
   while(1)  {
     r = av_read_frame(formatContext, &pkt);
+    if(r != 0)  { /*  No more frame, seek head and replay */
+      av_seek_frame(formatContext, 0, 1, AVSEEK_FLAG_BACKWARD);
+      r = av_read_frame(formatContext, &pkt);
+    }
     if(r != 0)
       break;  /*  No more frame */
 
@@ -367,11 +387,16 @@
         i, pkt.stream_index, pkt.dts, pkt.size, pkt.data);
     av_pkt_dump(stdout, &pkt, 0);
 #endif
+    if(pkt.flags & PKT_FLAG_KEY)
+      printf("Key frame %d\n", i);
 
     unsigned char *lp = 0;
     int len = 0;
-    filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
-
+ //   filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags | PKT_FLAG_KEY));
+    r = filterContext->filter->filter(filterContext, codecContext, NULL, &lp, &len, pkt.data, pkt.size, (pkt.flags));
+    if(r != 1)
+      printf("Frame %d : Fail to filter ...\n", i);
+//printf("Frame %d: %d\n", pkt.stream_index, len);
     decode_mfc(lp, len);
 
     av_free_packet(&pkt);
@@ -393,7 +418,7 @@
       } else
         break;
     }
-#if 0
+#if 1
     i++;
 #endif
   }
@@ -403,6 +428,10 @@
 
   avcodec_close(is->codec);
 
+  munmap(fb_addr, fb_size);
+    close(pp_fd);
+    close(fb_fd);
+
   deinit_mfc();
 
   return 0;


沒有留言:

張貼留言