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;
沒有留言:
張貼留言