FFmpeg a problem with a flower screen on some machines.
The original code such as the following:
while (Av_read_frame (Formatctx, &packet) >=0 &&!_stop && null!=window && binit) {//are This a packet from the video stream?if (packet.stream_index==videostream) {//Decode video Frameavcodec_decode_video2 ( Codecctx, Decodedframe, &framefinished, &packet);/Did we get a video frame?if (framefinished) {//Convert the I Mage from it native format to Rgbasws_scale (SWS_CTX, (uint8_t const * const *) decodedframe->data,decodedframe-> Linesize,0,codecctx->height,framergba->data,framergba->linesize); if (Packet.dts = = AV_NOPTS_VALUE & & Decodedframe->opaque && * (uint64_t*) Decodedframe->opaque! = Av_nopts_value) {pts = * (uint64_t *) decodedframe->opaque; LOGD ("Pst1:%d", pts); else if (Packet.dts! = av_nopts_value) {pts = Packet.dts; LOGD ("Pst2:%d", pts); else {pts = 0; LOGD ("Pst3:%d", pts); pts = av_q2d (codecctx->time_base) * 1000000.0 * i * 2;pts *= 1000;//logd ("Debug%d,%d,%f", pts, (Long) (Av_q2d (codecctx ->time_Base) * 1000000.0 * I * 2), av_q2d (codecctx->time_base)); if (0 = = Pts | | 0 = = basetime) {basetime = Av_gettime ()-pts; LOGD ("Basetime:%d", basetime);} Else{waittime = (Basetime + pts)-av_gettime (); LOGD ("WAITTIME:%d,%d", waittime,pts);} WaitTime = (av_q2d (codecctx->time_base) * 1000.0-0.0) * 1000;IF (waittime>0) usleep (waitTime); if (!_stop) { Synchronized (Lockwindow) {if (!_stop && Null!=window) {//Lock the window Bufferif (Anativewindow_lock (Pwin, &windowbuffer, NULL) < 0) {LOGE ("Cannot lock Window");} else {//Draw the frame on buffer//logd ("Copy buffer%d:%d: %d ", width, height, width*height*rgb_size);//LOGD (" Window buffer:%d:%d:%d ", Windowbuffer.width, Windowbuffer.height, Windowbuffer.stride); memcpy (windowbuffer.bits, buffer, Width * height * rgb_size);//unlock the window buffer and post it To Displayanativewindow_unlockandpost (Pwin);//count number of Frames++i;}}}}After careful analysis, it is found that some resolution can be displayed normally, the feeling is caused by the width dislocation, such as the following:
org:176 * 144 F
x2:352 288 O
x3:528 432 F
x4:704 576 O
x6:1056 * O
X1.1 193 158 F
X1.2 211 172 F
X1.5 216 F
X0.5 (F)
X2?
: 352 290 O
X2?: 352 O
X2?: 352 720 O
X4?: 704 720 O
X6?: 1056 720 O
---1312
1056
1184
1248 OK
Find resolution in accordance with%64+32 alignment, feeling is caused by memory alignment, view Anativewindow_buffer such as the following
typedef struct ANATIVEWINDOW_BUFFER {//The number of pixels that is show horizontally. int32_t width; The number of pixels that is shown vertically. int32_t height; The number of *pixels* that a line in the buffer takes in //memory. This is >= width. int32_t Stride; The format of the buffer. One of window_format_* int32_t FORMAT; The actual bits. void* bits; Do not touch. uint32_t reserved[6];} Anativewindow_buffer;
Output stride and width of the log found, assuming the normal display is stride==width, through the gaze can be seen to be caused by memory alignment problems, adjust the code:
if (Packet.stream_index==videostream) {//Decode video Frameavcodec_decode_video2 (Codecctx, Decodedframe, & Framefinished, &packet);/Did we get a video frame?if (framefinished) {//Convert the image from it native format to Rgbasws_scale (SWS_CTX, (uint8_t const * const *) DECODEDFR Ame->data,decodedframe->linesize,0,codecctx->height,framergba->data,framergba->linesize); if ( Packet.dts = = Av_nopts_value && decodedframe->opaque && * (uint64_t*) Decodedframe->opaque! = AV_ Nopts_value) {pts = * (uint64_t *) decodedframe->opaque; LOGD ("Pst1:%d", pts); else if (Packet.dts! = av_nopts_value) {pts = Packet.dts; LOGD ("Pst2:%d", pts); else {pts = 0; LOGD ("Pst3:%d", pts); pts = av_q2d (codecctx->time_base) * 1000000.0 * i * 2;pts *= 1000;//logd ("Debug%d,%d,%f", pts, (Long) (Av_q2d (codecctx ->time_base) * 1000000.0 * I * 2), av_q2d (codecctx->time_base)); if (0 = = Pts | | 0 = = basetime) {basetime = Av_gettime ( )-pts; LOGD ("Basetime:%d", basetime);} Else{waittime = (Basetime + pts)-av_gettime (); LOGD ("WAITTIME:%d,%d", waittime,pts);} WaitTime = (av_q2d (codecctx->time_base) * 1000.0-0.0) * 1000;IF (waittime>0) Usleep (waitTime), if (!_stop) {synchronized (Lockwindow) {if (!_stop && Null!=window) {//Lock the window Bufferif (Anativewindow_lock (Pwin, &windowbuffer, NULL) < 0) {LOGE ("Cannot lock Window");} else {//Draw the frame On BUFFER//LOGD ("Copy buffer%d:%d:%d", width, height, width*height*rgb_size);//LOGD ("Window buffer:%d:%d:%d", Windowbuffer.width, Windowbuffer.height, windowbuffer.stride);//memcpy (windowbuffer.bits, buffer, Width * Height * RGB _size); if (Windowbuffer.width >= windowbuffer.stride) {memcpy (windowbuffer.bits, buffer, Width * height * rgb_size);} Else{//skip stride-width Skip padding partial memory for (int i=0;i
Through the line copy method, after jumping to face the memory of the aligned part,
Solve this problem,
FFmpeg on Android Output slide screen problem processing