static void flip_page(struct vo *vo) { struct vo_priv *p = vo->priv; pthread_mutex_lock(&p->ctx->lock); while (p->ctx->queued_frames >= p->frame_queue_size) { switch (p->frame_drop_mode) { case FRAME_DROP_CLEAR: frame_queue_drop_all(p->ctx); break; case FRAME_DROP_POP: frame_queue_shrink(p->ctx, p->frame_queue_size - 1); break; case FRAME_DROP_BLOCK: ; struct timespec ts = mp_rel_time_to_timespec(0.2); if (p->ctx->frozen || pthread_cond_timedwait(&p->ctx->wakeup, &p->ctx->lock, &ts)) { frame_queue_drop_all(p->ctx); p->ctx->frozen = true; } break; } } frame_queue_push(p->ctx, p->ctx->waiting_frame); p->ctx->waiting_frame = NULL; update(p); pthread_mutex_unlock(&p->ctx->lock); }
static void flip_page(struct vo *vo) { struct vo_priv *p = vo->priv; pthread_mutex_lock(&p->ctx->lock); if (p->ctx->queued_frames >= p->frame_queue_size) { if (p->frame_drop_mode == FRAME_DROP_CLEAR) frame_queue_drop_all(p->ctx); else // FRAME_DROP_POP mode frame_queue_shrink(p->ctx, p->frame_queue_size - 1); } frame_queue_push(p->ctx, p->ctx->waiting_frame); p->ctx->waiting_frame = NULL; update(p); pthread_mutex_unlock(&p->ctx->lock); }
static int audio_thread(void *arg) { VideoState *is = (VideoState*)arg; AVFrame *frame = av_frame_alloc(); Frame *af; int got_frame = 0; AVPacket pkt1, *pkt = &pkt1; do { if (packet_queue_get(&is->audioq, pkt, 1) < 0) { break; } avcodec_decode_audio4(is->audio_ctx, frame, &got_frame, pkt); if (got_frame) { af = frame_queue_peek_writable(&is->sampq); av_frame_move_ref(af->frame, frame); frame_queue_push(&is->sampq); av_free_packet(pkt); } } while(1); av_frame_free(&frame); return 0; }
int video_thread(void *arg) { VideoState *is = (VideoState *)arg; AVPacket pkt1, *pkt = &pkt1; int got_frame = 0; AVFrame *frame = av_frame_alloc(); Frame *vp; for (;;) { if (packet_queue_get(&is->videoq, pkt, 1) < 0) { // means we quit getting packets break; } // Decode video frame avcodec_decode_video2(is->video_ctx, frame, &got_frame, pkt); // Did we get a video frame? if (got_frame) { vp = frame_queue_peek_writable(&is->pictq); if (!vp->bmp || !vp->allocated || vp->width != frame->width || vp->height != frame->height) { SDL_Event event; vp->allocated = 0; vp->width = frame->width; vp->height = frame->height; /* the allocation must be done in the main thread to avoid locking problems. */ event.type = FF_ALLOC_EVENT; event.user.data1 = is; SDL_PushEvent(&event); /* wait until the picture is allocated */ SDL_LockMutex(is->pictq.mutex); while (!vp->allocated) { SDL_CondWait(is->pictq.cond, is->pictq.mutex); } SDL_UnlockMutex(is->pictq.mutex); } /* if the frame is not skipped, then display it */ if (vp->bmp) { AVPicture pict = { { 0 } }; /* get a pointer on the bitmap */ SDL_LockYUVOverlay(vp->bmp); pict.data[0] = vp->bmp->pixels[0]; pict.data[1] = vp->bmp->pixels[2]; pict.data[2] = vp->bmp->pixels[1]; pict.linesize[0] = vp->bmp->pitches[0]; pict.linesize[1] = vp->bmp->pitches[2]; pict.linesize[2] = vp->bmp->pitches[1]; is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, vp->width, vp->height, is->video_ctx->pix_fmt, vp->width, vp->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); sws_scale(is->img_convert_ctx, frame->data, frame->linesize, 0, vp->height, pict.data, pict.linesize); SDL_UnlockYUVOverlay(vp->bmp); /* 移动指针 */ frame_queue_push(&is->pictq); } av_free_packet(pkt); } } av_frame_free(&frame); return 0; }