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

📄 ffmpeg.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif    if (n > 0) {        n = read(0, &ch, 1);        if (n == 1)            return ch;        return n;    }#elif defined(HAVE_CONIO_H)    if(kbhit())        return(getch());#endif    return -1;}static int decode_interrupt_cb(void){    return q_pressed || (q_pressed = read_key() == 'q');}static int read_ffserver_streams(AVFormatContext *s, const char *filename){    int i, err;    AVFormatContext *ic;    err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL);    if (err < 0)        return err;    /* copy stream format */    s->nb_streams = ic->nb_streams;    for(i=0;i<ic->nb_streams;i++) {        AVStream *st;        // FIXME: a more elegant solution is needed        st = av_mallocz(sizeof(AVStream));        memcpy(st, ic->streams[i], sizeof(AVStream));        st->codec = avcodec_alloc_context();        memcpy(st->codec, ic->streams[i]->codec, sizeof(AVCodecContext));        s->streams[i] = st;    }    av_close_input_file(ic);    return 0;}static doubleget_sync_ipts(const AVOutputStream *ost){    const AVInputStream *ist = ost->sync_ist;    return (double)(ist->pts - start_time)/AV_TIME_BASE;}static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){    int ret;    while(bsfc){        AVPacket new_pkt= *pkt;        int a= av_bitstream_filter_filter(bsfc, avctx, NULL,                                          &new_pkt.data, &new_pkt.size,                                          pkt->data, pkt->size,                                          pkt->flags & PKT_FLAG_KEY);        if(a>0){            av_free_packet(pkt);            new_pkt.destruct= av_destruct_packet;        } else if(a<0){            fprintf(stderr, "%s failed for stream %d, codec %s",                    bsfc->filter->name, pkt->stream_index,                    avctx->codec ? avctx->codec->name : "copy");            print_error("", a);        }        *pkt= new_pkt;        bsfc= bsfc->next;    }    ret= av_interleaved_write_frame(s, pkt);    if(ret < 0){        print_error("av_interleaved_write_frame()", ret);        exit(1);    }}#define MAX_AUDIO_PACKET_SIZE (128 * 1024)static void do_audio_out(AVFormatContext *s,                         AVOutputStream *ost,                         AVInputStream *ist,                         unsigned char *buf, int size){    uint8_t *buftmp;    static uint8_t *audio_buf = NULL;    static uint8_t *audio_out = NULL;    const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE;    int size_out, frame_bytes, ret;    AVCodecContext *enc= ost->st->codec;    AVCodecContext *dec= ist->st->codec;    /* SC: dynamic allocation of buffers */    if (!audio_buf)        audio_buf = av_malloc(2*MAX_AUDIO_PACKET_SIZE);    if (!audio_out)        audio_out = av_malloc(audio_out_size);    if (!audio_buf || !audio_out)        return;               /* Should signal an error ! */    if (enc->channels != dec->channels)        ost->audio_resample = 1;    if (ost->audio_resample && !ost->resample) {        ost->resample = audio_resample_init(enc->channels,    dec->channels,                                            enc->sample_rate, dec->sample_rate);        if (!ost->resample) {            fprintf(stderr, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",                    dec->channels, dec->sample_rate,                    enc->channels, enc->sample_rate);            exit(1);        }    }    if(audio_sync_method){        double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts                - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);        double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate;        int byte_delta= ((int)idelta)*2*ist->st->codec->channels;        //FIXME resample delay        if(fabs(delta) > 50){            if(ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate){                if(byte_delta < 0){                    byte_delta= FFMAX(byte_delta, -size);                    size += byte_delta;                    buf  -= byte_delta;                    if(verbose > 2)                        fprintf(stderr, "discarding %d audio samples\n", (int)-delta);                    if(!size)                        return;                    ist->is_start=0;                }else{                    static uint8_t *input_tmp= NULL;                    input_tmp= av_realloc(input_tmp, byte_delta + size);                    if(byte_delta + size <= MAX_AUDIO_PACKET_SIZE)                        ist->is_start=0;                    else                        byte_delta= MAX_AUDIO_PACKET_SIZE - size;                    memset(input_tmp, 0, byte_delta);                    memcpy(input_tmp + byte_delta, buf, size);                    buf= input_tmp;                    size += byte_delta;                    if(verbose > 2)                        fprintf(stderr, "adding %d audio samples of silence\n", (int)delta);                }            }else if(audio_sync_method>1){                int comp= av_clip(delta, -audio_sync_method, audio_sync_method);                assert(ost->audio_resample);                if(verbose > 2)                    fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2));                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);            }        }    }else        ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)                        - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong    if (ost->audio_resample) {        buftmp = audio_buf;        size_out = audio_resample(ost->resample,                                  (short *)buftmp, (short *)buf,                                  size / (ist->st->codec->channels * 2));        size_out = size_out * enc->channels * 2;    } else {        buftmp = buf;        size_out = size;    }    /* now encode as many frames as possible */    if (enc->frame_size > 1) {        /* output resampled raw samples */        av_fifo_write(&ost->fifo, buftmp, size_out);        frame_bytes = enc->frame_size * 2 * enc->channels;        while (av_fifo_read(&ost->fifo, audio_buf, frame_bytes) == 0) {            AVPacket pkt;            av_init_packet(&pkt);            ret = avcodec_encode_audio(enc, audio_out, audio_out_size,                                       (short *)audio_buf);            audio_size += ret;            pkt.stream_index= ost->index;            pkt.data= audio_out;            pkt.size= ret;            if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)                pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);            pkt.flags |= PKT_FLAG_KEY;            write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);            ost->sync_opts += enc->frame_size;        }    } else {        AVPacket pkt;        av_init_packet(&pkt);        ost->sync_opts += size_out / (2 * enc->channels);        /* output a pcm frame */        /* XXX: change encoding codec API to avoid this ? */        switch(enc->codec->id) {        case CODEC_ID_PCM_S32LE:        case CODEC_ID_PCM_S32BE:        case CODEC_ID_PCM_U32LE:        case CODEC_ID_PCM_U32BE:            size_out = size_out << 1;            break;        case CODEC_ID_PCM_S24LE:        case CODEC_ID_PCM_S24BE:        case CODEC_ID_PCM_U24LE:        case CODEC_ID_PCM_U24BE:        case CODEC_ID_PCM_S24DAUD:            size_out = size_out / 2 * 3;            break;        case CODEC_ID_PCM_S16LE:        case CODEC_ID_PCM_S16BE:        case CODEC_ID_PCM_U16LE:        case CODEC_ID_PCM_U16BE:            break;        default:            size_out = size_out >> 1;            break;        }        ret = avcodec_encode_audio(enc, audio_out, size_out,                                   (short *)buftmp);        audio_size += ret;        pkt.stream_index= ost->index;        pkt.data= audio_out;        pkt.size= ret;        if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)            pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);        pkt.flags |= PKT_FLAG_KEY;        write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);    }}static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void **bufp){    AVCodecContext *dec;    AVPicture *picture2;    AVPicture picture_tmp;    uint8_t *buf = 0;    dec = ist->st->codec;    /* deinterlace : must be done before any resize */    if (do_deinterlace || using_vhook) {        int size;        /* create temporary picture */        size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);        buf = av_malloc(size);        if (!buf)            return;        picture2 = &picture_tmp;        avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);        if (do_deinterlace){            if(avpicture_deinterlace(picture2, picture,                                     dec->pix_fmt, dec->width, dec->height) < 0) {                /* if error, do not deinterlace */                av_free(buf);                buf = NULL;                picture2 = picture;            }        } else {            av_picture_copy(picture2, picture, dec->pix_fmt, dec->width, dec->height);        }    } else {        picture2 = picture;    }    if (ENABLE_VHOOK)        frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height,                           1000000 * ist->pts / AV_TIME_BASE);    if (picture != picture2)        *picture = *picture2;    *bufp = buf;}/* we begin to correct av delay at this threshold */#define AV_DELAY_MAX 0.100static void do_subtitle_out(AVFormatContext *s,                            AVOutputStream *ost,                            AVInputStream *ist,                            AVSubtitle *sub,                            int64_t pts){    static uint8_t *subtitle_out = NULL;    int subtitle_out_max_size = 65536;    int subtitle_out_size, nb, i;    AVCodecContext *enc;    AVPacket pkt;    if (pts == AV_NOPTS_VALUE) {        fprintf(stderr, "Subtitle packets must have a pts\n");        return;    }    enc = ost->st->codec;    if (!subtitle_out) {        subtitle_out = av_malloc(subtitle_out_max_size);    }    /* Note: DVB subtitle need one packet to draw them and one other       packet to clear them */    /* XXX: signal it in the codec context ? */    if (enc->codec_id == CODEC_ID_DVB_SUBTITLE)        nb = 2;    else        nb = 1;    for(i = 0; i < nb; i++) {        subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out,                                                    subtitle_out_max_size, sub);        av_init_packet(&pkt);        pkt.stream_index = ost->index;        pkt.data = subtitle_out;        pkt.size = subtitle_out_size;        pkt.pts = av_rescale_q(pts, ist->st->time_base, ost->st->time_base);        if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) {            /* XXX: the pts correction is handled here. Maybe handling               it in the codec would be better */            if (i == 0)                pkt.pts += 90 * sub->start_display_time;            else                pkt.pts += 90 * sub->end_display_time;        }        write_frame(s, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);    }}static int bit_buffer_size= 1024*256;static uint8_t *bit_buffer= NULL;static void do_video_out(AVFormatContext *s,                         AVOutputStream *ost,                         AVInputStream *ist,                         AVFrame *in_picture,                         int *frame_size){    int nb_frames, i, ret;

⌨️ 快捷键说明

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