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

📄 ffplay.c

📁 symbian下ffmpeg编程。。废了好大劲下下来的!。
💻 C
📖 第 1 页 / 共 5 页
字号:
            u1 = u;            v1 = v;            a1 = a;            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);            YUVA_IN(y, u, v, a, p + BPP, pal);            u1 += u;            v1 += v;            a1 += a;            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);            cb++;            cr++;            p += 2 * BPP;            lum += 2;        }        if (w) {            YUVA_IN(y, u, v, a, p, pal);            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);        }    }}static void free_subpicture(SubPicture *sp){    int i;    for (i = 0; i < sp->sub.num_rects; i++)    {        av_free(sp->sub.rects[i].bitmap);        av_free(sp->sub.rects[i].rgba_palette);    }    av_free(sp->sub.rects);    memset(&sp->sub, 0, sizeof(AVSubtitle));}static void video_image_display(VideoState *is){    VideoPicture *vp;    SubPicture *sp;    AVPicture pict;    float aspect_ratio;    int width, height, x, y;    SDL_Rect rect;    int i;    vp = &is->pictq[is->pictq_rindex];    if (vp->bmp) {        /* XXX: use variable in the frame */        if (is->video_st->codec->sample_aspect_ratio.num == 0)            aspect_ratio = 0;        else            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio)                * is->video_st->codec->width / is->video_st->codec->height;;        if (aspect_ratio <= 0.0)            aspect_ratio = (float)is->video_st->codec->width /                (float)is->video_st->codec->height;        /* if an active format is indicated, then it overrides the           mpeg format */#if 0        if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {            is->dtg_active_format = is->video_st->codec->dtg_active_format;            printf("dtg_active_format=%d\n", is->dtg_active_format);        }#endif#if 0        switch(is->video_st->codec->dtg_active_format) {        case FF_DTG_AFD_SAME:        default:            /* nothing to do */            break;        case FF_DTG_AFD_4_3:            aspect_ratio = 4.0 / 3.0;            break;        case FF_DTG_AFD_16_9:            aspect_ratio = 16.0 / 9.0;            break;        case FF_DTG_AFD_14_9:            aspect_ratio = 14.0 / 9.0;            break;        case FF_DTG_AFD_4_3_SP_14_9:            aspect_ratio = 14.0 / 9.0;            break;        case FF_DTG_AFD_16_9_SP_14_9:            aspect_ratio = 14.0 / 9.0;            break;        case FF_DTG_AFD_SP_4_3:            aspect_ratio = 4.0 / 3.0;            break;        }#endif        if (is->subtitle_st)        {            if (is->subpq_size > 0)            {                sp = &is->subpq[is->subpq_rindex];                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))                {                    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];                    for (i = 0; i < sp->sub.num_rects; i++)                        blend_subrect(&pict, &sp->sub.rects[i]);                    SDL_UnlockYUVOverlay (vp->bmp);                }            }        }        /* XXX: we suppose the screen has a 1.0 pixel ratio */        height = is->height;        width = ((int)rint(height * aspect_ratio)) & -3;        if (width > is->width) {            width = is->width;            height = ((int)rint(width / aspect_ratio)) & -3;        }        x = (is->width - width) / 2;        y = (is->height - height) / 2;        if (!is->no_background) {            /* fill the background */            //            fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00));        } else {            is->no_background = 0;        }        rect.x = is->xleft + x;        rect.y = is->xleft + y;        rect.w = width;        rect.h = height;        SDL_DisplayYUVOverlay(vp->bmp, &rect);    } else {#if 0        fill_rectangle(screen,                       is->xleft, is->ytop, is->width, is->height,                       QERGB(0x00, 0x00, 0x00));#endif    }}static inline int compute_mod(int a, int b){    a = a % b;    if (a >= 0)        return a;    else        return a + b;}static void video_audio_display(VideoState *s){    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;    int ch, channels, h, h2, bgcolor, fgcolor;    int16_t time_diff;    /* compute display index : center on currently output samples */    channels = s->audio_st->codec->channels;    nb_display_channels = channels;    if (!s->paused) {        n = 2 * channels;        delay = audio_write_get_buf_size(s);        delay /= n;        /* to be more precise, we take into account the time spent since           the last buffer computation */        if (audio_callback_time) {            time_diff = av_gettime() - audio_callback_time;            delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000;        }        delay -= s->width / 2;        if (delay < s->width)            delay = s->width;        i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);        s->last_i_start = i_start;    } else {        i_start = s->last_i_start;    }    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);    fill_rectangle(screen,                   s->xleft, s->ytop, s->width, s->height,                   bgcolor);    fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);    /* total height for one channel */    h = s->height / nb_display_channels;    /* graph height / 2 */    h2 = (h * 9) / 20;    for(ch = 0;ch < nb_display_channels; ch++) {        i = i_start + ch;        y1 = s->ytop + ch * h + (h / 2); /* position of center line */        for(x = 0; x < s->width; x++) {            y = (s->sample_array[i] * h2) >> 15;            if (y < 0) {                y = -y;                ys = y1 - y;            } else {                ys = y1;            }            fill_rectangle(screen,                           s->xleft + x, ys, 1, y,                           fgcolor);            i += channels;            if (i >= SAMPLE_ARRAY_SIZE)                i -= SAMPLE_ARRAY_SIZE;        }    }    fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);    for(ch = 1;ch < nb_display_channels; ch++) {        y = s->ytop + ch * h;        fill_rectangle(screen,                       s->xleft, y, s->width, 1,                       fgcolor);    }    SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);}/* display the current picture, if any */static void video_display(VideoState *is){    if (is->audio_st && is->show_audio)        video_audio_display(is);    else if (is->video_st)        video_image_display(is);}static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque){    SDL_Event event;    event.type = FF_REFRESH_EVENT;    event.user.data1 = opaque;    SDL_PushEvent(&event);    return 0; /* 0 means stop timer */}/* schedule a video refresh in 'delay' ms */static void schedule_refresh(VideoState *is, int delay){    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);}/* get the current audio clock value */static double get_audio_clock(VideoState *is){    double pts;    int hw_buf_size, bytes_per_sec;    pts = is->audio_clock;    hw_buf_size = audio_write_get_buf_size(is);    bytes_per_sec = 0;    if (is->audio_st) {        bytes_per_sec = is->audio_st->codec->sample_rate *            2 * is->audio_st->codec->channels;    }    if (bytes_per_sec)        pts -= (double)hw_buf_size / bytes_per_sec;    return pts;}/* get the current video clock value */static double get_video_clock(VideoState *is){    double delta;    if (is->paused) {        delta = 0;    } else {        delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;    }    return is->video_current_pts + delta;}/* get the current external clock value */static double get_external_clock(VideoState *is){    int64_t ti;    ti = av_gettime();    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);}/* get the current master clock value */static double get_master_clock(VideoState *is){    double val;    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {        if (is->video_st)            val = get_video_clock(is);        else            val = get_audio_clock(is);    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {        if (is->audio_st)            val = get_audio_clock(is);        else            val = get_video_clock(is);    } else {        val = get_external_clock(is);    }    return val;}/* seek in the stream */static void stream_seek(VideoState *is, int64_t pos, int rel){    if (!is->seek_req) {        is->seek_pos = pos;        is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0;        if (seek_by_bytes)            is->seek_flags |= AVSEEK_FLAG_BYTE;        is->seek_req = 1;    }}/* pause or resume the video */static void stream_pause(VideoState *is){    is->paused = !is->paused;    if (is->paused) {        is->video_current_pts = get_video_clock(is);    }}/* called to display each frame */void video_refresh_timer(void *opaque){    VideoState *is = opaque;    VideoPicture *vp;    double actual_delay, delay, sync_threshold, ref_clock, diff;    SubPicture *sp, *sp2;    if (is->video_st) {        if (is->pictq_size == 0) {            /* if no picture, need to wait */            schedule_refresh(is, 1);        } else {            /* dequeue the picture */            vp = &is->pictq[is->pictq_rindex];            /* update current video pts */            is->video_current_pts = vp->pts;            is->video_current_pts_time = av_gettime();            /* compute nominal delay */            delay = vp->pts - is->frame_last_pts;            if (delay <= 0 || delay >= 1.0) {                /* if incorrect delay, use previous one */                delay = is->frame_last_delay;            }            is->frame_last_delay = delay;            is->frame_last_pts = vp->pts;            /* update delay to follow master synchronisation source */            if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||                 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {                /* if video is slave, we try to correct big delays by                   duplicating or deleting a frame */                ref_clock = get_master_clock(is);                diff = vp->pts - ref_clock;                /* skip or repeat frame. We take into account the                   delay to compute the threshold. I still don't know                   if it is the best guess */                sync_threshold = AV_SYNC_THRESHOLD;                if (delay > sync_threshold)                    sync_threshold = delay;                if (fabs(diff) < AV_NOSYNC_THRESHOLD) {                    if (diff <= -sync_threshold)                        delay = 0;                    else if (diff >= sync_threshold)                        delay = 2 * delay;                }            }            is->frame_timer += delay;            /* compute the REAL delay (we need to do that to avoid               long term errors */            actual_delay = is->frame_timer - (av_gettime() / 1000000.0);            if (actual_delay < 0.010) {                /* XXX: should skip picture */                actual_delay = 0.010;            }            /* launch timer for next picture */            schedule_refresh(is, (int)(actual_delay * 1000 + 0.5));#if defined(DEBUG_SYNC)            printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n",                   delay, actual_delay, vp->pts, -diff);#endif            if(is->subtitle_st) {                if (is->subtitle_stream_changed) {                    SDL_LockMutex(is->subpq_mutex);                    while (is->subpq_size) {                        free_subpicture(&is->subpq[is->subpq_rindex]);                        /* update queue size and signal for next picture */                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)                            is->subpq_rindex = 0;                        is->subpq_size--;                    }                    is->subtitle_stream_changed = 0;                    SDL_CondSignal(is->subpq_cond);                    SDL_UnlockMutex(is->subpq_mutex);                } else {                    if (is->subpq_size > 0) {                        sp = &is->subpq[is->subpq_rindex];                        if (is->subpq_size > 1)                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];                        else                            sp2 = NULL;                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))                        {                            free_subpicture(sp);                            /* update queue size and signal for next picture */                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)                                is->subpq_rindex = 0;

⌨️ 快捷键说明

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