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

📄 ffplay.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());            return -1;        }        is->audio_hw_buf_size = spec.size;    }    if(thread_count>1)        avcodec_thread_init(enc, thread_count);    enc->thread_count= thread_count;    switch(enc->codec_type) {    case CODEC_TYPE_AUDIO:        is->audio_stream = stream_index;        is->audio_st = ic->streams[stream_index];        is->audio_buf_size = 0;        is->audio_buf_index = 0;        /* init averaging filter */        is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);        is->audio_diff_avg_count = 0;        /* since we do not have a precise anough audio fifo fullness,           we correct audio sync only if larger than this threshold */        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));        packet_queue_init(&is->audioq);        SDL_PauseAudio(0);        break;    case CODEC_TYPE_VIDEO:        is->video_stream = stream_index;        is->video_st = ic->streams[stream_index];        is->frame_last_delay = 40e-3;        is->frame_timer = (double)av_gettime() / 1000000.0;        is->video_current_pts_time = av_gettime();        packet_queue_init(&is->videoq);        is->video_tid = SDL_CreateThread(video_thread, is);        enc->    get_buffer=     my_get_buffer;        enc->release_buffer= my_release_buffer;        break;    case CODEC_TYPE_SUBTITLE:        is->subtitle_stream = stream_index;        is->subtitle_st = ic->streams[stream_index];        packet_queue_init(&is->subtitleq);        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);        break;    default:        break;    }    return 0;}static void stream_component_close(VideoState *is, int stream_index){    AVFormatContext *ic = is->ic;    AVCodecContext *enc;    if (stream_index < 0 || stream_index >= ic->nb_streams)        return;    enc = ic->streams[stream_index]->codec;    switch(enc->codec_type) {    case CODEC_TYPE_AUDIO:        packet_queue_abort(&is->audioq);        SDL_CloseAudio();        packet_queue_end(&is->audioq);        break;    case CODEC_TYPE_VIDEO:        packet_queue_abort(&is->videoq);        /* note: we also signal this mutex to make sure we deblock the           video thread in all cases */        SDL_LockMutex(is->pictq_mutex);        SDL_CondSignal(is->pictq_cond);        SDL_UnlockMutex(is->pictq_mutex);        SDL_WaitThread(is->video_tid, NULL);        packet_queue_end(&is->videoq);        break;    case CODEC_TYPE_SUBTITLE:        packet_queue_abort(&is->subtitleq);        /* note: we also signal this mutex to make sure we deblock the           video thread in all cases */        SDL_LockMutex(is->subpq_mutex);        is->subtitle_stream_changed = 1;        SDL_CondSignal(is->subpq_cond);        SDL_UnlockMutex(is->subpq_mutex);        SDL_WaitThread(is->subtitle_tid, NULL);        packet_queue_end(&is->subtitleq);        break;    default:        break;    }    avcodec_close(enc);    switch(enc->codec_type) {    case CODEC_TYPE_AUDIO:        is->audio_st = NULL;        is->audio_stream = -1;        break;    case CODEC_TYPE_VIDEO:        is->video_st = NULL;        is->video_stream = -1;        break;    case CODEC_TYPE_SUBTITLE:        is->subtitle_st = NULL;        is->subtitle_stream = -1;        break;    default:        break;    }}static void dump_stream_info(const AVFormatContext *s){    if (s->track != 0)        fprintf(stderr, "Track: %d\n", s->track);    if (s->title[0] != '\0')        fprintf(stderr, "Title: %s\n", s->title);    if (s->author[0] != '\0')        fprintf(stderr, "Author: %s\n", s->author);    if (s->copyright[0] != '\0')        fprintf(stderr, "Copyright: %s\n", s->copyright);    if (s->comment[0] != '\0')        fprintf(stderr, "Comment: %s\n", s->comment);    if (s->album[0] != '\0')        fprintf(stderr, "Album: %s\n", s->album);    if (s->year != 0)        fprintf(stderr, "Year: %d\n", s->year);    if (s->genre[0] != '\0')        fprintf(stderr, "Genre: %s\n", s->genre);}/* since we have only one decoding thread, we can use a global   variable instead of a thread local variable */static VideoState *global_video_state;static int decode_interrupt_cb(void){    return (global_video_state && global_video_state->abort_request);}/* this thread gets the stream from the disk or the network */static int decode_thread(void *arg){    VideoState *is = arg;    AVFormatContext *ic;    int err, i, ret, video_index, audio_index;    AVPacket pkt1, *pkt = &pkt1;    AVFormatParameters params, *ap = &params;    video_index = -1;    audio_index = -1;    is->video_stream = -1;    is->audio_stream = -1;    is->subtitle_stream = -1;    global_video_state = is;    url_set_interrupt_cb(decode_interrupt_cb);    memset(ap, 0, sizeof(*ap));    ap->width = frame_width;    ap->height= frame_height;    ap->time_base= (AVRational){1, 25};    ap->pix_fmt = frame_pix_fmt;    err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);    if (err < 0) {        print_error(is->filename, err);        ret = -1;        goto fail;    }    is->ic = ic;    if(genpts)        ic->flags |= AVFMT_FLAG_GENPTS;    err = av_find_stream_info(ic);    if (err < 0) {        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);        ret = -1;        goto fail;    }    if(ic->pb)        ic->pb->eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end    /* if seeking requested, we execute it */    if (start_time != AV_NOPTS_VALUE) {        int64_t timestamp;        timestamp = start_time;        /* add the stream start time */        if (ic->start_time != AV_NOPTS_VALUE)            timestamp += ic->start_time;        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);        if (ret < 0) {            fprintf(stderr, "%s: could not seek to position %0.3f\n",                    is->filename, (double)timestamp / AV_TIME_BASE);        }    }    for(i = 0; i < ic->nb_streams; i++) {        AVCodecContext *enc = ic->streams[i]->codec;        switch(enc->codec_type) {        case CODEC_TYPE_AUDIO:            if ((audio_index < 0 || wanted_audio_stream-- > 0) && !audio_disable)                audio_index = i;            break;        case CODEC_TYPE_VIDEO:            if ((video_index < 0 || wanted_video_stream-- > 0) && !video_disable)                video_index = i;            break;        default:            break;        }    }    if (show_status) {        dump_format(ic, 0, is->filename, 0);        dump_stream_info(ic);    }    /* open the streams */    if (audio_index >= 0) {        stream_component_open(is, audio_index);    }    if (video_index >= 0) {        stream_component_open(is, video_index);    } else {        if (!display_disable)            is->show_audio = 1;    }    if (is->video_stream < 0 && is->audio_stream < 0) {        fprintf(stderr, "%s: could not open codecs\n", is->filename);        ret = -1;        goto fail;    }    for(;;) {        if (is->abort_request)            break;        if (is->paused != is->last_paused) {            is->last_paused = is->paused;            if (is->paused)                av_read_pause(ic);            else                av_read_play(ic);        }#if defined(CONFIG_RTSP_DEMUXER) || defined(CONFIG_MMSH_PROTOCOL)        if (is->paused &&                (!strcmp(ic->iformat->name, "rtsp") ||                 (ic->pb && !strcmp(url_fileno(ic->pb)->prot->name, "mmsh")))) {            /* wait 10 ms to avoid trying to get another packet */            /* XXX: horrible */            SDL_Delay(10);            continue;        }#endif        if (is->seek_req) {            int stream_index= -1;            int64_t seek_target= is->seek_pos;            if     (is->   video_stream >= 0) stream_index= is->   video_stream;            else if(is->   audio_stream >= 0) stream_index= is->   audio_stream;            else if(is->subtitle_stream >= 0) stream_index= is->subtitle_stream;            if(stream_index>=0){                seek_target= av_rescale_q(seek_target, AV_TIME_BASE_Q, ic->streams[stream_index]->time_base);            }            ret = av_seek_frame(is->ic, stream_index, seek_target, is->seek_flags);            if (ret < 0) {                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);            }else{                if (is->audio_stream >= 0) {                    packet_queue_flush(&is->audioq);                    packet_queue_put(&is->audioq, &flush_pkt);                }                if (is->subtitle_stream >= 0) {                    packet_queue_flush(&is->subtitleq);                    packet_queue_put(&is->subtitleq, &flush_pkt);                }                if (is->video_stream >= 0) {                    packet_queue_flush(&is->videoq);                    packet_queue_put(&is->videoq, &flush_pkt);                }            }            is->seek_req = 0;        }        /* if the queue are full, no need to read more */        if (is->audioq.size > MAX_AUDIOQ_SIZE ||            is->videoq.size > MAX_VIDEOQ_SIZE ||            is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||            url_feof(ic->pb)) {            /* wait 10 ms */            SDL_Delay(10);            continue;        }        ret = av_read_frame(ic, pkt);        if (ret < 0) {            if (url_ferror(ic->pb) == 0) {                SDL_Delay(100); /* wait for user event */                continue;            } else                break;        }        if (pkt->stream_index == is->audio_stream) {            packet_queue_put(&is->audioq, pkt);        } else if (pkt->stream_index == is->video_stream) {            packet_queue_put(&is->videoq, pkt);        } else if (pkt->stream_index == is->subtitle_stream) {            packet_queue_put(&is->subtitleq, pkt);        } else {            av_free_packet(pkt);        }    }    /* wait until the end */    while (!is->abort_request) {        SDL_Delay(100);    }    ret = 0; fail:    /* disable interrupting */    global_video_state = NULL;    /* close each stream */    if (is->audio_stream >= 0)        stream_component_close(is, is->audio_stream);    if (is->video_stream >= 0)        stream_component_close(is, is->video_stream);    if (is->subtitle_stream >= 0)        stream_component_close(is, is->subtitle_stream);    if (is->ic) {        av_close_input_file(is->ic);        is->ic = NULL; /* safety */    }    url_set_interrupt_cb(NULL);    if (ret != 0) {        SDL_Event event;        event.type = FF_QUIT_EVENT;        event.user.data1 = is;        SDL_PushEvent(&event);    }    return 0;}static VideoState *stream_open(const char *filename, AVInputFormat *iformat){    VideoState *is;    is = av_mallocz(sizeof(VideoState));    if (!is)        return NULL;    av_strlcpy(is->filename, filename, sizeof(is->filename));    is->iformat = iformat;    is->ytop = 0;    is->xleft = 0;    /* start video display */    is->pictq_mutex = SDL_CreateMutex();    is->pictq_cond = SDL_CreateCond();    is->subpq_mutex = SDL_CreateMutex();    is->subpq_cond = SDL_CreateCond();    /* add the refresh timer to draw the picture */    schedule_refresh(is, 40);    is->av_sync_type = av_sync_type;    is->parse_tid = SDL_CreateThread(decode_thread, is);    if (!is->parse_tid) {        av_free(is);        return NULL;    }    return is;}static void stream_close(VideoState *is){    VideoPicture *vp;    int i;    /* XXX: use a special url_shutdown call to abort parse cleanly */    is->abort_request = 1;    SDL_WaitThread(is->parse_tid, NULL);    /* free all pictures */    for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {        vp = &is->pictq[i];        if (vp->bmp) {            SDL_FreeYUVOverlay(vp->bmp);            vp->bmp = NULL;        }    }    SDL_DestroyMutex(is->pictq_mutex);    SDL_DestroyCond(is->pictq_cond);    SDL_DestroyMutex(is->subpq_mutex);    SDL_DestroyCond(is->subpq_cond);}static void stream_cycle_channel(VideoState *is, int codec_type){    AVFormatContext *ic = is->ic;    int start_index, stream_index;    AVStream *st;    if (codec_type == CODEC_TYPE_VIDEO)        start_index = is->video_stream;    else if (codec_type == CODEC_TYPE_AUDIO)        start_index = is->audio_stream;    else        start_index = is->subtitle_stream;    if (st

⌨️ 快捷键说明

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