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

📄 ffmpeg.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
    ptr = pkt->data;    while (len > 0) {    handle_eof:        /* decode the packet if needed */        data_buf = NULL; /* fail safe */        data_size = 0;        subtitle_to_free = NULL;        if (ist->decoding_needed) {            switch(ist->st->codec->codec_type) {            case CODEC_TYPE_AUDIO:{                if(pkt)                    samples= av_fast_realloc(samples, &samples_size, FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE));                data_size= samples_size;                    /* XXX: could avoid copy if PCM 16 bits with same                       endianness as CPU */                ret = avcodec_decode_audio2(ist->st->codec, samples, &data_size,                                           ptr, len);                if (ret < 0)                    goto fail_decode;                ptr += ret;                len -= ret;                /* Some bug in mpeg audio decoder gives */                /* data_size < 0, it seems they are overflows */                if (data_size <= 0) {                    /* no audio frame */                    continue;                }                data_buf = (uint8_t *)samples;                ist->next_pts += ((int64_t)AV_TIME_BASE/2 * data_size) /                    (ist->st->codec->sample_rate * ist->st->codec->channels);                break;}            case CODEC_TYPE_VIDEO:                    data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2;                    /* XXX: allocate picture correctly */                    avcodec_get_frame_defaults(&picture);                    ret = avcodec_decode_video(ist->st->codec,                                               &picture, &got_picture, ptr, len);                    ist->st->quality= picture.quality;                    if (ret < 0)                        goto fail_decode;                    if (!got_picture) {                        /* no picture yet */                        goto discard_packet;                    }                    if (ist->st->codec->time_base.num != 0) {                        ist->next_pts += ((int64_t)AV_TIME_BASE *                                          ist->st->codec->time_base.num) /                            ist->st->codec->time_base.den;                    }                    len = 0;                    break;            case CODEC_TYPE_SUBTITLE:                ret = avcodec_decode_subtitle(ist->st->codec,                                              &subtitle, &got_subtitle, ptr, len);                if (ret < 0)                    goto fail_decode;                if (!got_subtitle) {                    goto discard_packet;                }                subtitle_to_free = &subtitle;                len = 0;                break;            default:                goto fail_decode;            }        } else {            switch(ist->st->codec->codec_type) {            case CODEC_TYPE_AUDIO:                ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /                    ist->st->codec->sample_rate;                break;            case CODEC_TYPE_VIDEO:                if (ist->st->codec->time_base.num != 0) {                    ist->next_pts += ((int64_t)AV_TIME_BASE *                                      ist->st->codec->time_base.num) /                        ist->st->codec->time_base.den;                }                break;            }            data_buf = ptr;            data_size = len;            ret = len;            len = 0;        }        buffer_to_free = NULL;        if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {            pre_process_video_frame(ist, (AVPicture *)&picture,                                    &buffer_to_free);        }        // preprocess audio (volume)        if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {            if (audio_volume != 256) {                short *volp;                volp = samples;                for(i=0;i<(data_size / sizeof(short));i++) {                    int v = ((*volp) * audio_volume + 128) >> 8;                    if (v < -32768) v = -32768;                    if (v >  32767) v = 32767;                    *volp++ = v;                }            }        }        /* frame rate emulation */        if (ist->st->codec->rate_emu) {            int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den);            int64_t now = av_gettime() - ist->start;            if (pts > now)                usleep(pts - now);            ist->frame++;        }#if 0        /* mpeg PTS deordering : if it is a P or I frame, the PTS           is the one of the next displayed one */        /* XXX: add mpeg4 too ? */        if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) {            if (ist->st->codec->pict_type != B_TYPE) {                int64_t tmp;                tmp = ist->last_ip_pts;                ist->last_ip_pts  = ist->frac_pts.val;                ist->frac_pts.val = tmp;            }        }#endif        /* if output time reached then transcode raw format,           encode packets and output them */        if (start_time == 0 || ist->pts >= start_time)            for(i=0;i<nb_ostreams;i++) {                int frame_size;                ost = ost_table[i];                if (ost->source_index == ist_index) {                    os = output_files[ost->file_index];#if 0                    printf("%d: got pts=%0.3f %0.3f\n", i,                           (double)pkt->pts / AV_TIME_BASE,                           ((double)ist->pts / AV_TIME_BASE) -                           ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den));#endif                    /* set the input output pts pairs */                    //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;                    if (ost->encoding_needed) {                        switch(ost->st->codec->codec_type) {                        case CODEC_TYPE_AUDIO:                            do_audio_out(os, ost, ist, data_buf, data_size);                            break;                        case CODEC_TYPE_VIDEO:                            do_video_out(os, ost, ist, &picture, &frame_size);                            video_size += frame_size;                            if (vstats_filename && frame_size)                                do_video_stats(os, ost, frame_size);                            break;                        case CODEC_TYPE_SUBTITLE:                            do_subtitle_out(os, ost, ist, &subtitle,                                            pkt->pts);                            break;                        default:                            abort();                        }                    } else {                        AVFrame avframe; //FIXME/XXX remove this                        AVPacket opkt;                        av_init_packet(&opkt);                        if (!ost->frame_number && !(pkt->flags & PKT_FLAG_KEY))                            continue;                        /* no reencoding needed : output the packet directly */                        /* force the input stream PTS */                        avcodec_get_frame_defaults(&avframe);                        ost->st->codec->coded_frame= &avframe;                        avframe.key_frame = pkt->flags & PKT_FLAG_KEY;                        if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO)                            audio_size += data_size;                        else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) {                            video_size += data_size;                            ost->sync_opts++;                        }                        opkt.stream_index= ost->index;                        if(pkt->pts != AV_NOPTS_VALUE)                            opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base);                        else                            opkt.pts= AV_NOPTS_VALUE;                            if (pkt->dts == AV_NOPTS_VALUE)                                opkt.dts = av_rescale_q(ist->next_pts, AV_TIME_BASE_Q, ost->st->time_base);                            else                                opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);                        opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);                        opkt.flags= pkt->flags;                        //FIXME remove the following 2 lines they shall be replaced by the bitstream filters                        if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY))                            opkt.destruct= av_destruct_packet;                        write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][opkt.stream_index]);                        ost->st->codec->frame_number++;                        ost->frame_number++;                        av_free_packet(&opkt);                    }                }            }        av_free(buffer_to_free);        /* XXX: allocate the subtitles in the codec ? */        if (subtitle_to_free) {            if (subtitle_to_free->rects != NULL) {                for (i = 0; i < subtitle_to_free->num_rects; i++) {                    av_free(subtitle_to_free->rects[i].bitmap);                    av_free(subtitle_to_free->rects[i].rgba_palette);                }                av_freep(&subtitle_to_free->rects);            }            subtitle_to_free->num_rects = 0;            subtitle_to_free = NULL;        }    } discard_packet:    if (pkt == NULL) {        /* EOF handling */        for(i=0;i<nb_ostreams;i++) {            ost = ost_table[i];            if (ost->source_index == ist_index) {                AVCodecContext *enc= ost->st->codec;                os = output_files[ost->file_index];                if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO && enc->frame_size <=1)                    continue;                if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))                    continue;                if (ost->encoding_needed) {                    for(;;) {                        AVPacket pkt;                        int fifo_bytes;                        av_init_packet(&pkt);                        pkt.stream_index= ost->index;                        switch(ost->st->codec->codec_type) {                        case CODEC_TYPE_AUDIO:                            fifo_bytes = av_fifo_size(&ost->fifo);                            ret = 0;                            /* encode any samples remaining in fifo */                            if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {                                int fs_tmp = enc->frame_size;                                enc->frame_size = fifo_bytes / (2 * enc->channels);                                if(av_fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes) == 0) {                                    ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);                                }                                enc->frame_size = fs_tmp;                            }                            if(ret <= 0) {                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);                            }                            audio_size += ret;                            pkt.flags |= PKT_FLAG_KEY;                            break;                        case CODEC_TYPE_VIDEO:                            ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);                            video_size += ret;                            if(enc->coded_frame && enc->coded_frame->key_frame)                                pkt.flags |= PKT_FLAG_KEY;                            if (ost->logfile && enc->stats_out) {                                fprintf(ost->logfile, "%s", enc->stats_out);                            }                            break;                        default:                            ret=-1;                        }                        if(ret<=0)                            break;                        pkt.data= bit_buffer;                        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);                        write_frame(os, &pkt, ost->st->codec, bitstream_filters[ost->file_index][pkt.stream_index]);                    }                }            }        }    }    return 0; fail_decode:    return -1;}static void print_sdp(AVFormatContext **avc, int n){    char sdp[2048];    avf_sdp_create(avc, n, sdp, sizeof(sdp));    printf("SDP:\n%s\n", sdp);}static int stream_index_from_inputs(AVFormatContext **input_files,                                    int nb_input_files,                                    AVInputFile *file_table,                                    AVInputStream **ist_table,                                    enum CodecType type,                                    int programid){    int p, q, z;    for(z=0; z<nb_input_files; z++) {        AVFormatContext *ic = input_files[z];        for(p=0; p<ic->nb_programs; p++) {            AVProgram *program = ic->programs[p];            if(program->id != programid)                continue;            for(q=0; q<program->nb_stream_indexes; q++) {                int sidx = program->stream_index[q];                int ris = file_table[z].ist_index + sidx;                if(ist_table[ris]->discard && ic->streams[sidx]->codec->codec_type == type)                    return ris;            }        }    }    return -1;}/* * The following code is the main loop of the file converter */static int av_encode(AVFormatContext **output_files,                     int nb_output_files,                     AVFormatContext **input_files,                     int nb_input_files,                     AVStreamMap *stream_maps, int nb_stream_maps){    int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;    AVFormatContext *is, *os;    AVCodecContext *codec, *icodec;    AVOutputStream *ost, **ost_table = NULL;    AVInputStream *ist, **ist_table = NULL;    AVInputFile *file_table;    int key;    int want_sdp = 1;    file_table= av_mallocz(nb_input_files * sizeof(AVInputFile));    if (!file_table)        goto fail;    /* input stream init */    j = 0;

⌨️ 快捷键说明

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