⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ffplay.c

📁 symbian下ffmpeg编程。。废了好大劲下下来的!。
💻 C
📖 第 1 页 / 共 5 页
字号:
                            SDL_LockMutex(is->subpq_mutex);                            is->subpq_size--;                            SDL_CondSignal(is->subpq_cond);                            SDL_UnlockMutex(is->subpq_mutex);                        }                    }                }            }            /* display picture */            video_display(is);            /* update queue size and signal for next picture */            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)                is->pictq_rindex = 0;            SDL_LockMutex(is->pictq_mutex);            is->pictq_size--;            SDL_CondSignal(is->pictq_cond);            SDL_UnlockMutex(is->pictq_mutex);        }    } else if (is->audio_st) {        /* draw the next audio frame */        schedule_refresh(is, 40);        /* if only audio stream, then display the audio bars (better           than nothing, just to test the implementation */        /* display picture */        video_display(is);    } else {        schedule_refresh(is, 100);    }    if (show_status) {        static int64_t last_time;        int64_t cur_time;        int aqsize, vqsize, sqsize;        double av_diff;        cur_time = av_gettime();        if (!last_time || (cur_time - last_time) >= 500 * 1000) {            aqsize = 0;            vqsize = 0;            sqsize = 0;            if (is->audio_st)                aqsize = is->audioq.size;            if (is->video_st)                vqsize = is->videoq.size;            if (is->subtitle_st)                sqsize = is->subtitleq.size;            av_diff = 0;            if (is->audio_st && is->video_st)                av_diff = get_audio_clock(is) - get_video_clock(is);            printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB    \r",                   get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize);            fflush(stdout);            last_time = cur_time;        }    }}/* allocate a picture (needs to do that in main thread to avoid   potential locking problems */void alloc_picture(void *opaque){    VideoState *is = opaque;    VideoPicture *vp;    vp = &is->pictq[is->pictq_windex];    if (vp->bmp)        SDL_FreeYUVOverlay(vp->bmp);#if 0    /* XXX: use generic function */    /* XXX: disable overlay if no hardware acceleration or if RGB format */    switch(is->video_st->codec->pix_fmt) {    case PIX_FMT_YUV420P:    case PIX_FMT_YUV422P:    case PIX_FMT_YUV444P:    case PIX_FMT_YUV422:    case PIX_FMT_YUV410P:    case PIX_FMT_YUV411P:        is_yuv = 1;        break;    default:        is_yuv = 0;        break;    }#endif    vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,                                   is->video_st->codec->height,                                   SDL_YV12_OVERLAY,                                   screen);    vp->width = is->video_st->codec->width;    vp->height = is->video_st->codec->height;    SDL_LockMutex(is->pictq_mutex);    vp->allocated = 1;    SDL_CondSignal(is->pictq_cond);    SDL_UnlockMutex(is->pictq_mutex);}/** * * @param pts the dts of the pkt / pts of the frame and guessed if not known */static int queue_picture(VideoState *is, AVFrame *src_frame, double pts){    VideoPicture *vp;    int dst_pix_fmt;    AVPicture pict;    static struct SwsContext *img_convert_ctx;    /* wait until we have space to put a new picture */    SDL_LockMutex(is->pictq_mutex);    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&           !is->videoq.abort_request) {        SDL_CondWait(is->pictq_cond, is->pictq_mutex);    }    SDL_UnlockMutex(is->pictq_mutex);    if (is->videoq.abort_request)        return -1;    vp = &is->pictq[is->pictq_windex];    /* alloc or resize hardware picture buffer */    if (!vp->bmp ||        vp->width != is->video_st->codec->width ||        vp->height != is->video_st->codec->height) {        SDL_Event event;        vp->allocated = 0;        /* 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 && !is->videoq.abort_request) {            SDL_CondWait(is->pictq_cond, is->pictq_mutex);        }        SDL_UnlockMutex(is->pictq_mutex);        if (is->videoq.abort_request)            return -1;    }    /* if the frame is not skipped, then display it */    if (vp->bmp) {        /* get a pointer on the bitmap */        SDL_LockYUVOverlay (vp->bmp);        dst_pix_fmt = PIX_FMT_YUV420P;        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];        if (img_convert_ctx == NULL) {            img_convert_ctx = sws_getContext(is->video_st->codec->width,                    is->video_st->codec->height, is->video_st->codec->pix_fmt,                    is->video_st->codec->width, is->video_st->codec->height,                    dst_pix_fmt, sws_flags, NULL, NULL, NULL);            if (img_convert_ctx == NULL) {                fprintf(stderr, "Cannot initialize the conversion context\n");                exit(1);            }        }        sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,                  0, is->video_st->codec->height, pict.data, pict.linesize);        /* update the bitmap content */        SDL_UnlockYUVOverlay(vp->bmp);        vp->pts = pts;        /* now we can update the picture count */        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)            is->pictq_windex = 0;        SDL_LockMutex(is->pictq_mutex);        is->pictq_size++;        SDL_UnlockMutex(is->pictq_mutex);    }    return 0;}/** * compute the exact PTS for the picture if it is omitted in the stream * @param pts1 the dts of the pkt / pts of the frame */static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1){    double frame_delay, pts;    pts = pts1;    if (pts != 0) {        /* update video clock with pts, if present */        is->video_clock = pts;    } else {        pts = is->video_clock;    }    /* update video clock for next frame */    frame_delay = av_q2d(is->video_st->codec->time_base);    /* for MPEG2, the frame can be repeated, so we update the       clock accordingly */    frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);    is->video_clock += frame_delay;#if defined(DEBUG_SYNC) && 0    {        int ftype;        if (src_frame->pict_type == FF_B_TYPE)            ftype = 'B';        else if (src_frame->pict_type == FF_I_TYPE)            ftype = 'I';        else            ftype = 'P';        printf("frame_type=%c clock=%0.3f pts=%0.3f\n",               ftype, pts, pts1);    }#endif    return queue_picture(is, src_frame, pts);}static int video_thread(void *arg){    VideoState *is = arg;    AVPacket pkt1, *pkt = &pkt1;    int len1, got_picture;    AVFrame *frame= avcodec_alloc_frame();    double pts;    for(;;) {        while (is->paused && !is->videoq.abort_request) {            SDL_Delay(10);        }        if (packet_queue_get(&is->videoq, pkt, 1) < 0)            break;        if(pkt->data == flush_pkt.data){            avcodec_flush_buffers(is->video_st->codec);            continue;        }        /* NOTE: ipts is the PTS of the _first_ picture beginning in           this packet, if any */        pts = 0;        if (pkt->dts != AV_NOPTS_VALUE)            pts = av_q2d(is->video_st->time_base)*pkt->dts;            len1 = avcodec_decode_video(is->video_st->codec,                                        frame, &got_picture,                                        pkt->data, pkt->size);//            if (len1 < 0)//                break;            if (got_picture) {                if (output_picture2(is, frame, pts) < 0)                    goto the_end;            }        av_free_packet(pkt);        if (step)            if (cur_stream)                stream_pause(cur_stream);    } the_end:    av_free(frame);    return 0;}static int subtitle_thread(void *arg){    VideoState *is = arg;    SubPicture *sp;    AVPacket pkt1, *pkt = &pkt1;    int len1, got_subtitle;    double pts;    int i, j;    int r, g, b, y, u, v, a;    for(;;) {        while (is->paused && !is->subtitleq.abort_request) {            SDL_Delay(10);        }        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)            break;        if(pkt->data == flush_pkt.data){            avcodec_flush_buffers(is->subtitle_st->codec);            continue;        }        SDL_LockMutex(is->subpq_mutex);        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&               !is->subtitleq.abort_request) {            SDL_CondWait(is->subpq_cond, is->subpq_mutex);        }        SDL_UnlockMutex(is->subpq_mutex);        if (is->subtitleq.abort_request)            goto the_end;        sp = &is->subpq[is->subpq_windex];       /* NOTE: ipts is the PTS of the _first_ picture beginning in           this packet, if any */        pts = 0;        if (pkt->pts != AV_NOPTS_VALUE)            pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;        len1 = avcodec_decode_subtitle(is->subtitle_st->codec,                                    &sp->sub, &got_subtitle,                                    pkt->data, pkt->size);//            if (len1 < 0)//                break;        if (got_subtitle && sp->sub.format == 0) {            sp->pts = pts;            for (i = 0; i < sp->sub.num_rects; i++)            {                for (j = 0; j < sp->sub.rects[i].nb_colors; j++)                {                    RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);                    y = RGB_TO_Y_CCIR(r, g, b);                    u = RGB_TO_U_CCIR(r, g, b, 0);                    v = RGB_TO_V_CCIR(r, g, b, 0);                    YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);                }            }            /* now we can update the picture count */            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)                is->subpq_windex = 0;            SDL_LockMutex(is->subpq_mutex);            is->subpq_size++;            SDL_UnlockMutex(is->subpq_mutex);        }        av_free_packet(pkt);//        if (step)//            if (cur_stream)//                stream_pause(cur_stream);    } the_end:    return 0;}/* copy samples for viewing in editor window */static void update_sample_display(VideoState *is, short *samples, int samples_size){    int size, len, channels;    channels = is->audio_st->codec->channels;    size = samples_size / sizeof(short);    while (size > 0) {        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;        if (len > size)            len = size;        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));        samples += len;        is->sample_array_index += len;        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)            is->sample_array_index = 0;        size -= len;    }}/* return the new audio buffer size (samples can be added or deleted   to get better sync if video or external master clock) */static int synchronize_audio(VideoState *is, short *samples,                             int samples_size1, double pts){    int n, samples_size;    double ref_clock;    n = 2 * is->audio_st->codec->channels;    samples_size = samples_size1;    /* if not master, then we try to remove or add samples to correct the clock */    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {        double diff, avg_diff;        int wanted_size, min_size, max_size, nb_samples;        ref_clock = get_master_clock(is);        diff = get_audio_clock(is) - ref_clock;        if (diff < AV_NOSYNC_THRESHOLD) {            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {                /* not enough measures to have a correct estimate */                is->audio_diff_avg_count++;            } else {                /* estimate the A-V difference */                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);                if (fabs(avg_diff) >= is->audio_diff_threshold) {                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);                    nb_samples = samples_size / n;                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;                    if (wanted_size < min_size)                        wanted_size = min_size;                    else if (wanted_size > max_size)                        wanted_size = max_size;                    /* add or remove samples to correction the synchro */                    if (wanted_size < samples_size) {                        /* remove samples */                        samples_size = wanted_size;                    } else if (wanted_size > samples_size) {                        uint8_t *samples_end, *q;                        int nb;                        /* add samples */                        nb = (samples_size - wanted_size);                        samples_end = (uint8_t *)samples + samples_size - n;                        q = samples_end + n;                        while (nb > 0) {                            memcpy(q, samples_end, n);                            q += n;                            nb -= n;                        }                        samples_size = wanted_size;                    }                }#if 0                printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",                       diff, avg_diff, samples_size - samples_size1,                       is->audio_clock, is->video_clock, is->audio_diff_threshold);#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -