コード例 #1
0
ファイル: ffplayer.cpp プロジェクト: github188/SPlayer
static double get_clock(Clock *c)
{
	//if (*c->queue_serial != c->serial)
	//	return NAN;
	if (c->paused) {
		return c->pts;
	}
	else {
		double time = av_gettime_relative() / 1000000.0;
		return c->pts;
	//	return c->pts_drift + time - (time - c->last_updated) * (1.0 - c->speed);
	}
}
コード例 #2
0
ファイル: sapenc.c プロジェクト: NinjaRhyme/FFmpeg
static int sap_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVFormatContext *rtpctx;
    struct SAPState *sap = s->priv_data;
    int64_t now = av_gettime_relative();

    if (!sap->last_time || now - sap->last_time > 5000000) {
        int ret = ffurl_write(sap->ann_fd, sap->ann, sap->ann_size);
        /* Don't abort even if we get "Destination unreachable" */
        if (ret < 0 && ret != AVERROR(ECONNREFUSED))
            return ret;
        sap->last_time = now;
    }
    rtpctx = s->streams[pkt->stream_index]->priv_data;
    return ff_write_chained(rtpctx, 0, pkt, s);
}
コード例 #3
0
ファイル: ffdecoder.cpp プロジェクト: zhenghuadai/FFmpeg
int VideoDecoder::video_thread(void *arg)
{
    VideoState *is = (VideoState *) arg;
    AVStreamsParser* ps = is->getAVStreamsParser();
    AVFrame *frame = av_frame_alloc();
    double pts;
    double duration;
    int ret;
    AVRational tb = ps->video_st->time_base;
    AVRational frame_rate = av_guess_frame_rate(ps->ic, ps->video_st, NULL);

#if CONFIG_AVFILTER
    AVFilterGraph *graph = avfilter_graph_alloc();
    AVFilterContext *filt_out = NULL, *filt_in = NULL;
    int last_w = 0;
    int last_h = 0;
    enum AVPixelFormat last_format = (AVPixelFormat) (-2);
    int last_serial = -1;
    int last_vfilter_idx = 0;
    if (!graph) {
        av_frame_free(&frame);
        return AVERROR(ENOMEM);
    }

#endif

    if (!frame) {
#if CONFIG_AVFILTER
        avfilter_graph_free(&graph);
#endif
        return AVERROR(ENOMEM);
    }

    for (;;) {
        ret = is->viddec().get_video_frame(is, frame);
        if (ret < 0)
            goto the_end;
        if (!ret)
            continue;

#if CONFIG_AVFILTER
        if (   last_w != frame->width
            || last_h != frame->height
            || last_format != frame->format
            || last_serial != is->viddec().pkt_serial
            || last_vfilter_idx != is->vfilter_idx) {
            av_log(NULL, AV_LOG_DEBUG,
                   "Video frame changed from size:%dx%d format:%s serial:%d to size:%dx%d format:%s serial:%d\n",
                   last_w, last_h,
                   (const char *)av_x_if_null(av_get_pix_fmt_name(last_format), "none"), last_serial,
                   frame->width, frame->height,
                   (const char *)av_x_if_null(av_get_pix_fmt_name((AVPixelFormat)frame->format), "none"), is->viddec().pkt_serial);
            avfilter_graph_free(&graph);
            graph = avfilter_graph_alloc();
            if ((ret = configure_video_filters(graph, is,gOptions.vfilters_list ? gOptions.vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) {
                SDL_Event event;
                event.type = FF_QUIT_EVENT;
                event.user.data1 = is;
                SDL_PushEvent(&event);
                goto the_end;
            }
            filt_in  = is->in_video_filter;
            filt_out = is->out_video_filter;
            last_w = frame->width;
            last_h = frame->height;
            last_format = (AVPixelFormat) frame->format;
            last_serial = is->viddec().pkt_serial;
            last_vfilter_idx = is->vfilter_idx;
            frame_rate = filt_out->inputs[0]->frame_rate;
        }

        ret = av_buffersrc_add_frame(filt_in, frame);
        if (ret < 0)
            goto the_end;

        while (ret >= 0) {
            is->frame_last_returned_time = av_gettime_relative() / 1000000.0;

            ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
            if (ret < 0) {
                if (ret == AVERROR_EOF)
                    is->viddec().finished = is->viddec().pkt_serial;
                ret = 0;
                break;
            }

            is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time;
            if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
                is->frame_last_filter_delay = 0;
            tb = filt_out->inputs[0]->time_base;
#endif
            duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0);
            pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
            ret = queue_picture(is, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec().pkt_serial);
            av_frame_unref(frame);
#if CONFIG_AVFILTER
        }
#endif

        if (ret < 0)
            goto the_end;
    }
 the_end:
#if CONFIG_AVFILTER
    avfilter_graph_free(&graph);
#endif
    av_frame_free(&frame);
    return 0;
}
コード例 #4
0
ファイル: hls.c プロジェクト: lihp1603/libav
static int read_data(void *opaque, uint8_t *buf, int buf_size)
{
    struct variant *v = opaque;
    HLSContext *c = v->parent->priv_data;
    int ret, i;

restart:
    if (!v->input) {
        /* If this is a live stream and the reload interval has elapsed since
         * the last playlist reload, reload the variant playlists now. */
        int64_t reload_interval = v->n_segments > 0 ?
                                  v->segments[v->n_segments - 1]->duration :
                                  v->target_duration;

reload:
        if (!v->finished &&
            av_gettime_relative() - v->last_load_time >= reload_interval) {
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                return ret;
            /* If we need to reload the playlist again below (if
             * there's still no more segments), switch to a reload
             * interval of half the target duration. */
            reload_interval = v->target_duration / 2;
        }
        if (v->cur_seq_no < v->start_seq_no) {
            av_log(NULL, AV_LOG_WARNING,
                   "skipping %d segments ahead, expired from playlists\n",
                   v->start_seq_no - v->cur_seq_no);
            v->cur_seq_no = v->start_seq_no;
        }
        if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
            if (v->finished)
                return AVERROR_EOF;
            while (av_gettime_relative() - v->last_load_time < reload_interval) {
                if (ff_check_interrupt(c->interrupt_callback))
                    return AVERROR_EXIT;
                av_usleep(100*1000);
            }
            /* Enough time has elapsed since the last reload */
            goto reload;
        }

        ret = open_input(v);
        if (ret < 0)
            return ret;
    }
    ret = ffurl_read(v->input, buf, buf_size);
    if (ret > 0)
        return ret;
    ffurl_close(v->input);
    v->input = NULL;
    v->cur_seq_no++;

    c->end_of_segment = 1;
    c->cur_seq_no = v->cur_seq_no;

    if (v->ctx && v->ctx->nb_streams &&
        v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
        v->needed = 0;
        for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
             i++) {
            if (v->parent->streams[i]->discard < AVDISCARD_ALL)
                v->needed = 1;
        }
    }
    if (!v->needed) {
        av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
               v->index);
        return AVERROR_EOF;
    }
    goto restart;
}
コード例 #5
0
ファイル: hls.c プロジェクト: lihp1603/libav
static int parse_playlist(HLSContext *c, const char *url,
                          struct variant *var, AVIOContext *in)
{
    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    int64_t duration = 0;
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
    char key[MAX_URL_SIZE] = "";
    char line[1024];
    const char *ptr;
    int close_in = 0;
    uint8_t *new_url = NULL;

    if (!in) {
        ret = open_in(c, &in, url);
        if (ret < 0)
            return ret;
        close_in = 1;
    }

    if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
        url = new_url;

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    if (var) {
        free_segment_list(var);
        var->finished = 0;
    }
    while (!in->eof_reached) {
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atoi(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            if (var)
                var->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atof(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                seg->key_type = key_type;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = var->start_seq_no + var->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
    if (var)
        var->last_load_time = av_gettime_relative();

fail:
    av_free(new_url);
    if (close_in)
        avio_close(in);
    return ret;
}
コード例 #6
0
ファイル: ffplayer.cpp プロジェクト: github188/SPlayer
static void set_clock(Clock *c, double pts, int serial)
{
	double time = av_gettime_relative() / 1000000.0;
	set_clock_at(c, pts, serial, time);
}
コード例 #7
0
ファイル: rtspdec.c プロジェクト: DeHackEd/FFmpeg
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    RTSPState *rt = s->priv_data;
    int ret;
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];

retry:
    if (rt->server_type == RTSP_SERVER_REAL) {
        int i;

        for (i = 0; i < s->nb_streams; i++)
            rt->real_setup[i] = s->streams[i]->discard;

        if (!rt->need_subscription) {
            if (memcmp (rt->real_setup, rt->real_setup_cache,
                        sizeof(enum AVDiscard) * s->nb_streams)) {
                snprintf(cmd, sizeof(cmd),
                         "Unsubscribe: %s\r\n",
                         rt->last_subscription);
                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
                                 cmd, reply, NULL);
                if (reply->status_code != RTSP_STATUS_OK)
                    return ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
                rt->need_subscription = 1;
            }
        }

        if (rt->need_subscription) {
            int r, rule_nr, first = 1;

            memcpy(rt->real_setup_cache, rt->real_setup,
                   sizeof(enum AVDiscard) * s->nb_streams);
            rt->last_subscription[0] = 0;

            snprintf(cmd, sizeof(cmd),
                     "Subscribe: ");
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
                rule_nr = 0;
                for (r = 0; r < s->nb_streams; r++) {
                    if (s->streams[r]->id == i) {
                        if (s->streams[r]->discard != AVDISCARD_ALL) {
                            if (!first)
                                av_strlcat(rt->last_subscription, ",",
                                           sizeof(rt->last_subscription));
                            ff_rdt_subscribe_rule(
                                rt->last_subscription,
                                sizeof(rt->last_subscription), i, rule_nr);
                            first = 0;
                        }
                        rule_nr++;
                    }
                }
            }
            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
                             cmd, reply, NULL);
            if (reply->status_code != RTSP_STATUS_OK)
                return ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
            rt->need_subscription = 0;

            if (rt->state == RTSP_STATE_STREAMING)
                rtsp_read_play (s);
        }
    }

    ret = ff_rtsp_fetch_packet(s, pkt);
    if (ret < 0) {
        if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
                rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
                RTSPMessageHeader reply1, *reply = &reply1;
                av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
                if (rtsp_read_pause(s) != 0)
                    return -1;
                // TEARDOWN is required on Real-RTSP, but might make
                // other servers close the connection.
                if (rt->server_type == RTSP_SERVER_REAL)
                    ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
                                     reply, NULL);
                rt->session_id[0] = '\0';
                if (resetup_tcp(s) == 0) {
                    rt->state = RTSP_STATE_IDLE;
                    rt->need_subscription = 1;
                    if (rtsp_read_play(s) != 0)
                        return -1;
                    goto retry;
                }
            }
        }
        return ret;
    }
    rt->packets++;

    if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
        /* send dummy request to keep TCP connection alive */
        if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
            rt->auth_state.stale) {
            if (rt->server_type == RTSP_SERVER_WMS ||
                (rt->server_type != RTSP_SERVER_REAL &&
                 rt->get_parameter_supported)) {
                ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
            } else {
                ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
            }
            /* The stale flag should be reset when creating the auth response in
             * ff_rtsp_send_cmd_async, but reset it here just in case we never
             * called the auth code (if we didn't have any credentials set). */
            rt->auth_state.stale = 0;
        }
    }

    return 0;
}
コード例 #8
0
ファイル: hlsproto.c プロジェクト: DeHackEd/FFmpeg
static int parse_playlist(URLContext *h, const char *url)
{
    HLSContext *s = h->priv_data;
    AVIOContext *in;
    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
    int64_t duration = 0;
    char line[1024];
    const char *ptr;

    if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
                                   &h->interrupt_callback, NULL,
                                   h->protocol_whitelist, h->protocol_blacklist)) < 0)
        return ret;

    ff_get_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    free_segment_list(s);
    s->finished = 0;
    while (!avio_feof(in)) {
        ff_get_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
            s->target_duration = atoi(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            s->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
            s->finished = 1;
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration = atof(ptr) * AV_TIME_BASE;
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_segment) {
                struct segment *seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
                dynarray_add(&s->segments, &s->n_segments, seg);
                is_segment = 0;
            } else if (is_variant) {
                struct variant *var = av_malloc(sizeof(struct variant));
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                var->bandwidth = bandwidth;
                ff_make_absolute_url(var->url, sizeof(var->url), url, line);
                dynarray_add(&s->variants, &s->n_variants, var);
                is_variant = 0;
            }
        }
    }
    s->last_load_time = av_gettime_relative();

fail:
    avio_close(in);
    return ret;
}
コード例 #9
0
ファイル: hlsproto.c プロジェクト: DeHackEd/FFmpeg
static int hls_read(URLContext *h, uint8_t *buf, int size)
{
    HLSContext *s = h->priv_data;
    const char *url;
    int ret;
    int64_t reload_interval;

start:
    if (s->seg_hd) {
        ret = ffurl_read(s->seg_hd, buf, size);
        if (ret > 0)
            return ret;
    }
    if (s->seg_hd) {
        ffurl_close(s->seg_hd);
        s->seg_hd = NULL;
        s->cur_seq_no++;
    }
    reload_interval = s->n_segments > 0 ?
                      s->segments[s->n_segments - 1]->duration :
                      s->target_duration;
retry:
    if (!s->finished) {
        int64_t now = av_gettime_relative();
        if (now - s->last_load_time >= reload_interval) {
            if ((ret = parse_playlist(h, s->playlisturl)) < 0)
                return ret;
            /* If we need to reload the playlist again below (if
             * there's still no more segments), switch to a reload
             * interval of half the target duration. */
            reload_interval = s->target_duration / 2;
        }
    }
    if (s->cur_seq_no < s->start_seq_no) {
        av_log(h, AV_LOG_WARNING,
               "skipping %d segments ahead, expired from playlist\n",
               s->start_seq_no - s->cur_seq_no);
        s->cur_seq_no = s->start_seq_no;
    }
    if (s->cur_seq_no - s->start_seq_no >= s->n_segments) {
        if (s->finished)
            return AVERROR_EOF;
        while (av_gettime_relative() - s->last_load_time < reload_interval) {
            if (ff_check_interrupt(&h->interrupt_callback))
                return AVERROR_EXIT;
            av_usleep(100*1000);
        }
        goto retry;
    }
    url = s->segments[s->cur_seq_no - s->start_seq_no]->url;
    av_log(h, AV_LOG_DEBUG, "opening %s\n", url);
    ret = ffurl_open_whitelist(&s->seg_hd, url, AVIO_FLAG_READ,
                               &h->interrupt_callback, NULL,
                               h->protocol_whitelist, h->protocol_blacklist, h);
    if (ret < 0) {
        if (ff_check_interrupt(&h->interrupt_callback))
            return AVERROR_EXIT;
        av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url);
        s->cur_seq_no++;
        goto retry;
    }
    goto start;
}
コード例 #10
0
ファイル: fft-test.c プロジェクト: gajjanag/FFmpeg
int main(int argc, char **argv)
{
    FFTComplex *tab, *tab1, *tab_ref;
    FFTSample *tab2;
    enum tf_transform transform = TRANSFORM_FFT;
    FFTContext m, s;
#if FFT_FLOAT
    RDFTContext r;
    DCTContext d;
#if CONFIG_LIBFFTW3
    FFTWContext fftw;
    FFTWComplex *tab_fftw, *tab_fftw_copy;
#endif /* CONFIG_LIBFFTW3 */
#endif /* FFT_FLOAT */
    int it, i, err = 1;
    int do_speed = 0, do_inverse = 0;
    int fft_nbits = 9, fft_size;
    double scale = 1.0;
    AVLFG prng;

    av_lfg_init(&prng, 1);

    for (;;) {
        int c = getopt(argc, argv, "hsitmrdn:f:c:");
        if (c == -1)
            break;
        switch (c) {
        case 'h':
            help();
            return 1;
        case 's':
            do_speed = 1;
            break;
        case 'i':
            do_inverse = 1;
            break;
#if CONFIG_LIBFFTW3
        case 't':
            transform = TRANSFORM_FFTW;
            break;
#endif /* CONFIG_LIBFFTW3 */
        case 'm':
            transform = TRANSFORM_MDCT;
            break;
        case 'r':
            transform = TRANSFORM_RDFT;
            break;
        case 'd':
            transform = TRANSFORM_DCT;
            break;
        case 'n':
            fft_nbits = atoi(optarg);
            break;
        case 'f':
            scale = atof(optarg);
            break;
        case 'c':
        {
            unsigned cpuflags = av_get_cpu_flags();

            if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
                return 1;

            av_force_cpu_flags(cpuflags);
            break;
        }
        }
    }

    fft_size = 1 << fft_nbits;
    tab      = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab1     = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab_ref  = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab2     = av_malloc_array(fft_size, sizeof(FFTSample));
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    tab_fftw      = av_malloc_array(fft_size, sizeof(*tab_fftw));
    tab_fftw_copy = av_malloc_array(fft_size, sizeof(*tab_fftw_copy));
    if (!(tab_fftw && tab_fftw_copy))
        goto cleanup_fftw;
#endif /* CONFIG_LIBFFTW3 */

    if (!(tab && tab1 && tab_ref && tab2))
        goto cleanup;

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        av_log(NULL, AV_LOG_INFO, "Scale factor is set to %f\n", scale);
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IMDCT");
        else
            av_log(NULL, AV_LOG_INFO, "MDCT");
        ff_mdct_init(&m, fft_nbits, do_inverse, scale);
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IFFT");
        else
            av_log(NULL, AV_LOG_INFO, "FFT");
        ff_fft_init(&s, fft_nbits, do_inverse);
        if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
            goto cleanup;
        break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    case TRANSFORM_FFTW:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IFFTW");
        else
            av_log(NULL, AV_LOG_INFO, "FFTW");
        ff_fftw_init(&fftw, fft_size, do_inverse);
        if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
            goto cleanup;
        break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
#    if CONFIG_RDFT
    case TRANSFORM_RDFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "IDFT_C2R");
        else
            av_log(NULL, AV_LOG_INFO, "DFT_R2C");
        ff_rdft_init(&r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
        if ((err = fft_ref_init(fft_nbits, do_inverse)) < 0)
            goto cleanup;
        break;
#    endif /* CONFIG_RDFT */
#    if CONFIG_DCT
    case TRANSFORM_DCT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO, "DCT_III");
        else
            av_log(NULL, AV_LOG_INFO, "DCT_II");
        ff_dct_init(&d, fft_nbits, do_inverse ? DCT_III : DCT_II);
        break;
#    endif /* CONFIG_DCT */
#endif /* FFT_FLOAT */
    default:
        av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n");
        goto cleanup;
    }
    av_log(NULL, AV_LOG_INFO, " %d test\n", fft_size);

    /* generate random data */

    for (i = 0; i < fft_size; i++) {
        tab1[i].re = frandom(&prng);
        tab1[i].im = frandom(&prng);
#if CONFIG_LIBFFTW3 && FFT_FLOAT
        tab_fftw[i][0] = tab1[i].re;
        tab_fftw[i][1] = tab1[i].im;
#endif /* CONFIG_LIBFFTW3 */
    }
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    memcpy(tab_fftw_copy, tab_fftw, fft_size * sizeof(*tab_fftw));
#endif

    /* checking result */
    av_log(NULL, AV_LOG_INFO, "Checking...\n");

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        if (do_inverse) {
            imdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
            m.imdct_calc(&m, tab2, &tab1->re);
            err = check_diff(&tab_ref->re, tab2, fft_size, scale);
        } else {
            mdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
            m.mdct_calc(&m, tab2, &tab1->re);
            err = check_diff(&tab_ref->re, tab2, fft_size / 2, scale);
        }
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        s.fft_permute(&s, tab);
        s.fft_calc(&s, tab);

        fft_ref(tab_ref, tab1, fft_nbits);
        err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
        break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    case TRANSFORM_FFTW:
        fftw.fft_calc(&fftw, tab_fftw);
        fft_ref(tab_ref, tab1, fft_nbits);
        for (i = 0; i < fft_size; i++) {
            tab[i].re = tab_fftw[i][0];
            tab[i].im = tab_fftw[i][1];
        }
        err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
        break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
#if CONFIG_RDFT
    case TRANSFORM_RDFT:
    {
        int fft_size_2 = fft_size >> 1;
        if (do_inverse) {
            tab1[0].im          = 0;
            tab1[fft_size_2].im = 0;
            for (i = 1; i < fft_size_2; i++) {
                tab1[fft_size_2 + i].re =  tab1[fft_size_2 - i].re;
                tab1[fft_size_2 + i].im = -tab1[fft_size_2 - i].im;
            }

            memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
            tab2[1] = tab1[fft_size_2].re;

            r.rdft_calc(&r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            for (i = 0; i < fft_size; i++) {
                tab[i].re = tab2[i];
                tab[i].im = 0;
            }
            err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 0.5);
        } else {
            for (i = 0; i < fft_size; i++) {
                tab2[i]    = tab1[i].re;
                tab1[i].im = 0;
            }
            r.rdft_calc(&r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            tab_ref[0].im = tab_ref[fft_size_2].re;
            err = check_diff(&tab_ref->re, tab2, fft_size, 1.0);
        }
        break;
    }
#endif /* CONFIG_RDFT */
#if CONFIG_DCT
    case TRANSFORM_DCT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        d.dct_calc(&d, &tab->re);
        if (do_inverse)
            idct_ref(&tab_ref->re, &tab1->re, fft_nbits);
        else
            dct_ref(&tab_ref->re, &tab1->re, fft_nbits);
        err = check_diff(&tab_ref->re, &tab->re, fft_size, 1.0);
        break;
#endif /* CONFIG_DCT */
#endif /* FFT_FLOAT */
    }

    /* do a speed test */

    if (do_speed) {
        int64_t time_start, duration;
        int nb_its;

        av_log(NULL, AV_LOG_INFO, "Speed test...\n");
        /* we measure during about 1 seconds */
        nb_its = 1;
        for (;;) {
            time_start = av_gettime_relative();
            for (it = 0; it < nb_its; it++) {
                switch (transform) {
                case TRANSFORM_MDCT:
                    if (do_inverse)
                        m.imdct_calc(&m, &tab->re, &tab1->re);
                    else
                        m.mdct_calc(&m, &tab->re, &tab1->re);
                    break;
                case TRANSFORM_FFT:
                    memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
                    s.fft_permute(&s, tab);
                    s.fft_calc(&s, tab);
                    break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
                case TRANSFORM_FFTW:
                    memcpy(tab_fftw, tab_fftw_copy, fft_size * sizeof(*tab_fftw));
                    fftw.fft_calc(&fftw, tab_fftw);
                    break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
                case TRANSFORM_RDFT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    r.rdft_calc(&r, tab2);
                    break;
                case TRANSFORM_DCT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    d.dct_calc(&d, tab2);
                    break;
#endif /* FFT_FLOAT */
                }
            }
            duration = av_gettime_relative() - time_start;
            if (duration >= 1000000)
                break;
            nb_its *= 2;
        }
        av_log(NULL, AV_LOG_INFO,
               "time: %0.2f us/transform [total time=%0.2f s its=%d]\n",
               (double) duration / nb_its,
               (double) duration / 1000000.0,
               nb_its);
    }

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        ff_mdct_end(&m);
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        ff_fft_end(&s);
        break;
#if CONFIG_LIBFFTW3 && FFT_FLOAT
    case TRANSFORM_FFTW:
        ff_fftw_deinit(&fftw);
        break;
#endif /* CONFIG_LIBFFTW3 */
#if FFT_FLOAT
#    if CONFIG_RDFT
    case TRANSFORM_RDFT:
        ff_rdft_end(&r);
        break;
#    endif /* CONFIG_RDFT */
#    if CONFIG_DCT
    case TRANSFORM_DCT:
        ff_dct_end(&d);
        break;
#    endif /* CONFIG_DCT */
#endif /* FFT_FLOAT */
    }

#if CONFIG_LIBFFTW3 && FFT_FLOAT
cleanup_fftw:
    av_freep(&tab_fftw);
#endif /* CONFIG_LIBFFTW3 */
cleanup:
    av_freep(&tab);
    av_freep(&tab1);
    av_freep(&tab2);
    av_freep(&tab_ref);
    av_freep(&exptab);

    if (err)
        printf("Error: %d.\n", err);

    return !!err;
}
コード例 #11
0
ファイル: fft-test.c プロジェクト: AlexZhangOG/FFmpeg
int main(int argc, char **argv)
{
    FFTComplex *tab, *tab1, *tab_ref;
    FFTSample *tab2;
    int it, i, c;
    int cpuflags;
    int do_speed = 0;
    int err = 1;
    enum tf_transform transform = TRANSFORM_FFT;
    int do_inverse = 0;
    FFTContext s1, *s = &s1;
    FFTContext m1, *m = &m1;
#if FFT_FLOAT
    RDFTContext r1, *r = &r1;
    DCTContext d1, *d = &d1;
    int fft_size_2;
#endif
    int fft_nbits, fft_size;
    double scale = 1.0;
    AVLFG prng;
    av_lfg_init(&prng, 1);

    fft_nbits = 9;
    for(;;) {
        c = getopt(argc, argv, "hsimrdn:f:c:");
        if (c == -1)
            break;
        switch(c) {
        case 'h':
            help();
            return 1;
        case 's':
            do_speed = 1;
            break;
        case 'i':
            do_inverse = 1;
            break;
        case 'm':
            transform = TRANSFORM_MDCT;
            break;
        case 'r':
            transform = TRANSFORM_RDFT;
            break;
        case 'd':
            transform = TRANSFORM_DCT;
            break;
        case 'n':
            fft_nbits = atoi(optarg);
            break;
        case 'f':
            scale = atof(optarg);
            break;
        case 'c':
            cpuflags = av_get_cpu_flags();

            if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
                return 1;

            av_force_cpu_flags(cpuflags);
            break;
        }
    }

    fft_size = 1 << fft_nbits;
    tab = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab1 = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab_ref = av_malloc_array(fft_size, sizeof(FFTComplex));
    tab2 = av_malloc_array(fft_size, sizeof(FFTSample));

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        av_log(NULL, AV_LOG_INFO,"Scale factor is set to %f\n", scale);
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IMDCT");
        else
            av_log(NULL, AV_LOG_INFO,"MDCT");
        ff_mdct_init(m, fft_nbits, do_inverse, scale);
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IFFT");
        else
            av_log(NULL, AV_LOG_INFO,"FFT");
        ff_fft_init(s, fft_nbits, do_inverse);
        fft_ref_init(fft_nbits, do_inverse);
        break;
#if FFT_FLOAT
#    if CONFIG_RDFT
    case TRANSFORM_RDFT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"IDFT_C2R");
        else
            av_log(NULL, AV_LOG_INFO,"DFT_R2C");
        ff_rdft_init(r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
        fft_ref_init(fft_nbits, do_inverse);
        break;
#    endif /* CONFIG_RDFT */
#    if CONFIG_DCT
    case TRANSFORM_DCT:
        if (do_inverse)
            av_log(NULL, AV_LOG_INFO,"DCT_III");
        else
            av_log(NULL, AV_LOG_INFO,"DCT_II");
        ff_dct_init(d, fft_nbits, do_inverse ? DCT_III : DCT_II);
        break;
#    endif /* CONFIG_DCT */
#endif
    default:
        av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n");
        return 1;
    }
    av_log(NULL, AV_LOG_INFO," %d test\n", fft_size);

    /* generate random data */

    for (i = 0; i < fft_size; i++) {
        tab1[i].re = frandom(&prng);
        tab1[i].im = frandom(&prng);
    }

    /* checking result */
    av_log(NULL, AV_LOG_INFO,"Checking...\n");

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        if (do_inverse) {
            imdct_ref((FFTSample *)tab_ref, (FFTSample *)tab1, fft_nbits);
            m->imdct_calc(m, tab2, (FFTSample *)tab1);
            err = check_diff((FFTSample *)tab_ref, tab2, fft_size, scale);
        } else {
            mdct_ref((FFTSample *)tab_ref, (FFTSample *)tab1, fft_nbits);

            m->mdct_calc(m, tab2, (FFTSample *)tab1);

            err = check_diff((FFTSample *)tab_ref, tab2, fft_size / 2, scale);
        }
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        s->fft_permute(s, tab);
        s->fft_calc(s, tab);

        fft_ref(tab_ref, tab1, fft_nbits);
        err = check_diff((FFTSample *)tab_ref, (FFTSample *)tab, fft_size * 2, 1.0);
        break;
#if FFT_FLOAT
#if CONFIG_RDFT
    case TRANSFORM_RDFT:
        fft_size_2 = fft_size >> 1;
        if (do_inverse) {
            tab1[         0].im = 0;
            tab1[fft_size_2].im = 0;
            for (i = 1; i < fft_size_2; i++) {
                tab1[fft_size_2+i].re =  tab1[fft_size_2-i].re;
                tab1[fft_size_2+i].im = -tab1[fft_size_2-i].im;
            }

            memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
            tab2[1] = tab1[fft_size_2].re;

            r->rdft_calc(r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            for (i = 0; i < fft_size; i++) {
                tab[i].re = tab2[i];
                tab[i].im = 0;
            }
            err = check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 0.5);
        } else {
            for (i = 0; i < fft_size; i++) {
                tab2[i]    = tab1[i].re;
                tab1[i].im = 0;
            }
            r->rdft_calc(r, tab2);
            fft_ref(tab_ref, tab1, fft_nbits);
            tab_ref[0].im = tab_ref[fft_size_2].re;
            err = check_diff((float *)tab_ref, (float *)tab2, fft_size, 1.0);
        }
        break;
#endif /* CONFIG_RDFT */
#if CONFIG_DCT
    case TRANSFORM_DCT:
        memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
        d->dct_calc(d, (FFTSample *)tab);
        if (do_inverse) {
            idct_ref((FFTSample*)tab_ref, (FFTSample *)tab1, fft_nbits);
        } else {
            dct_ref((FFTSample*)tab_ref, (FFTSample *)tab1, fft_nbits);
        }
        err = check_diff((float *)tab_ref, (float *)tab, fft_size, 1.0);
        break;
#endif /* CONFIG_DCT */
#endif
    }

    /* do a speed test */

    if (do_speed) {
        int64_t time_start, duration;
        int nb_its;

        av_log(NULL, AV_LOG_INFO,"Speed test...\n");
        /* we measure during about 1 seconds */
        nb_its = 1;
        for(;;) {
            time_start = av_gettime_relative();
            for (it = 0; it < nb_its; it++) {
                switch (transform) {
                case TRANSFORM_MDCT:
                    if (do_inverse) {
                        m->imdct_calc(m, (FFTSample *)tab, (FFTSample *)tab1);
                    } else {
                        m->mdct_calc(m, (FFTSample *)tab, (FFTSample *)tab1);
                    }
                    break;
                case TRANSFORM_FFT:
                    memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
                    s->fft_calc(s, tab);
                    break;
#if FFT_FLOAT
                case TRANSFORM_RDFT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    r->rdft_calc(r, tab2);
                    break;
                case TRANSFORM_DCT:
                    memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
                    d->dct_calc(d, tab2);
                    break;
#endif
                }
            }
            duration = av_gettime_relative() - time_start;
            if (duration >= 1000000)
                break;
            nb_its *= 2;
        }
        av_log(NULL, AV_LOG_INFO,"time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
               (double)duration / nb_its,
               (double)duration / 1000000.0,
               nb_its);
    }

    switch (transform) {
#if CONFIG_MDCT
    case TRANSFORM_MDCT:
        ff_mdct_end(m);
        break;
#endif /* CONFIG_MDCT */
    case TRANSFORM_FFT:
        ff_fft_end(s);
        break;
#if FFT_FLOAT
#    if CONFIG_RDFT
    case TRANSFORM_RDFT:
        ff_rdft_end(r);
        break;
#    endif /* CONFIG_RDFT */
#    if CONFIG_DCT
    case TRANSFORM_DCT:
        ff_dct_end(d);
        break;
#    endif /* CONFIG_DCT */
#endif
    }

    av_free(tab);
    av_free(tab1);
    av_free(tab2);
    av_free(tab_ref);
    av_free(exptab);

    if (err)
        printf("Error: %d.\n", err);

    return !!err;
}
コード例 #12
0
ファイル: decklink_dec.cpp プロジェクト: chris-magic/xplayer
HRESULT decklink_input_callback::VideoInputFrameArrived(
    IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioFrame)
{
    void *frameBytes;
    void *audioFrameBytes;
    BMDTimeValue frameTime;
    BMDTimeValue frameDuration;
    int64_t wallclock = 0;

    ctx->frameCount++;
    if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK)
        wallclock = av_gettime_relative();

    // Handle Video Frame
    if (videoFrame) {
        AVPacket pkt;
        av_init_packet(&pkt);
        if (ctx->frameCount % 25 == 0) {
            unsigned long long qsize = avpacket_queue_size(&ctx->queue);
            av_log(avctx, AV_LOG_DEBUG,
                    "Frame received (#%lu) - Valid (%liB) - QSize %fMB\n",
                    ctx->frameCount,
                    videoFrame->GetRowBytes() * videoFrame->GetHeight(),
                    (double)qsize / 1024 / 1024);
        }

        videoFrame->GetBytes(&frameBytes);
        videoFrame->GetStreamTime(&frameTime, &frameDuration,
                                  ctx->video_st->time_base.den);

        if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
            if (ctx->draw_bars && videoFrame->GetPixelFormat() == bmdFormat8BitYUV) {
                unsigned bars[8] = {
                    0xEA80EA80, 0xD292D210, 0xA910A9A5, 0x90229035,
                    0x6ADD6ACA, 0x51EF515A, 0x286D28EF, 0x10801080 };
                int width  = videoFrame->GetWidth();
                int height = videoFrame->GetHeight();
                unsigned *p = (unsigned *)frameBytes;

                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x += 2)
                        *p++ = bars[(x * 8) / width];
                }
            }

            if (!no_video) {
                av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - No input signal detected "
                        "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
            }
            no_video = 1;
        } else {
            if (no_video) {
                av_log(avctx, AV_LOG_WARNING, "Frame received (#%lu) - Input returned "
                        "- Frames dropped %u\n", ctx->frameCount, ++ctx->dropped);
            }
            no_video = 0;
        }

        pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->video_pts_source, ctx->video_st->time_base, &initial_video_pts);
        pkt.dts = pkt.pts;

        pkt.duration = frameDuration;
        //To be made sure it still applies
        pkt.flags       |= AV_PKT_FLAG_KEY;
        pkt.stream_index = ctx->video_st->index;
        pkt.data         = (uint8_t *)frameBytes;
        pkt.size         = videoFrame->GetRowBytes() *
                           videoFrame->GetHeight();
        //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts);

#if CONFIG_LIBZVBI
        if (!no_video && ctx->teletext_lines && videoFrame->GetPixelFormat() == bmdFormat8BitYUV && videoFrame->GetWidth() == 720) {
            IDeckLinkVideoFrameAncillary *vanc;
            AVPacket txt_pkt;
            uint8_t txt_buf0[1611]; // max 35 * 46 bytes decoded teletext lines + 1 byte data_identifier
            uint8_t *txt_buf = txt_buf0;

            if (videoFrame->GetAncillaryData(&vanc) == S_OK) {
                int i;
                int64_t line_mask = 1;
                txt_buf[0] = 0x10;    // data_identifier - EBU_data
                txt_buf++;
                for (i = 6; i < 336; i++, line_mask <<= 1) {
                    uint8_t *buf;
                    if ((ctx->teletext_lines & line_mask) && vanc->GetBufferForVerticalBlankingLine(i, (void**)&buf) == S_OK) {
                        if (teletext_data_unit_from_vbi_data(i, buf, txt_buf) >= 0)
                            txt_buf += 46;
                    }
                    if (i == 22)
                        i = 317;
                }
                vanc->Release();
                if (txt_buf - txt_buf0 > 1) {
                    int stuffing_units = (4 - ((45 + txt_buf - txt_buf0) / 46) % 4) % 4;
                    while (stuffing_units--) {
                        memset(txt_buf, 0xff, 46);
                        txt_buf[1] = 0x2c; // data_unit_length
                        txt_buf += 46;
                    }
                    av_init_packet(&txt_pkt);
                    txt_pkt.pts = pkt.pts;
                    txt_pkt.dts = pkt.dts;
                    txt_pkt.stream_index = ctx->teletext_st->index;
                    txt_pkt.data = txt_buf0;
                    txt_pkt.size = txt_buf - txt_buf0;
                    if (avpacket_queue_put(&ctx->queue, &txt_pkt) < 0) {
                        ++ctx->dropped;
                    }
                }
            }
        }
#endif

        if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
            ++ctx->dropped;
        }
    }

    // Handle Audio Frame
    if (audioFrame) {
        AVPacket pkt;
        BMDTimeValue audio_pts;
        av_init_packet(&pkt);

        //hack among hacks
        pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codecpar->channels * (16 / 8);
        audioFrame->GetBytes(&audioFrameBytes);
        audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den);
        pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts);
        pkt.dts = pkt.pts;

        //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts);
        pkt.flags       |= AV_PKT_FLAG_KEY;
        pkt.stream_index = ctx->audio_st->index;
        pkt.data         = (uint8_t *)audioFrameBytes;

        if (avpacket_queue_put(&ctx->queue, &pkt) < 0) {
            ++ctx->dropped;
        }
    }

    return S_OK;
}
コード例 #13
0
ファイル: VideoStateInfo.cpp プロジェクト: ytxhao/ytxplayer
void VideoStateInfo::setClock(Clock *c, double pts, int serial) {

    double time = av_gettime_relative() / 1000000.0;
    setClockAt(c, pts, serial, time);

}
コード例 #14
0
ファイル: remuxing.c プロジェクト: DeYangLiu/ffmpeg-streaming
int main(int argc, char **argv)
{
    AVOutputFormat *ofmt = NULL;
    AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
	AVDictionary *out_opts = NULL;
    AVPacket pkt;
    const char *fmt, *in_filename, *out_filename;
    int ret, i, cmp;
	int cnt = 0;

    if (argc < 4) {
        printf("usage: remuxing input output fmt [do_sff do_rate_emu]\n");
        return 1;
    }
	if(argc >= 5){
		do_sff = atoi(argv[4]);
	}
	if(argc >= 6){
		do_rate_emu = atoi(argv[5]);
	}

    in_filename  = argv[1];
    out_filename = argv[2];
	fmt = argv[3];

    av_register_all();
    avformat_network_init();

    if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
        fprintf(stderr, "Could not open input file '%s'", in_filename);
        goto end;
    }

    if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
        fprintf(stderr, "Failed to retrieve input stream information");
        goto end;
    }

    av_dump_format(ifmt_ctx, 0, in_filename, 0);

    avformat_alloc_output_context2(&ofmt_ctx, NULL, fmt, out_filename);
    if (!ofmt_ctx) {
        fprintf(stderr, "Could not create output context\n");
        ret = AVERROR_UNKNOWN;
        goto end;
    }

    ofmt = ofmt_ctx->oformat;

    for (i = 0; i < ifmt_ctx->nb_streams; i++) {
        AVStream *in_stream = ifmt_ctx->streams[i];
        AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
        if (!out_stream) {
            fprintf(stderr, "Failed allocating output stream\n");
            ret = AVERROR_UNKNOWN;
            goto end;
        }
		
		avpriv_set_pts_info(out_stream, in_stream->pts_wrap_bits, in_stream->time_base.num, in_stream->time_base.den);
        ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
        if (ret < 0) {
            fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
            goto end;
        }
        out_stream->codec->codec_tag = 0;
        if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

	if(out_filename && strstr(out_filename, ".m3u8")){
		av_opt_set_int(ofmt_ctx, "hls_wrap",  6, AV_OPT_SEARCH_CHILDREN);
		av_opt_set_int(ofmt_ctx, "hls_list_size",  6, AV_OPT_SEARCH_CHILDREN); 
		av_opt_set(ofmt_ctx, "hls_time", "1.0", AV_OPT_SEARCH_CHILDREN);
	}

    av_dump_format(ofmt_ctx, 0, out_filename, 1);

    if (!(ofmt->flags & AVFMT_NOFILE)) {
		av_dict_set(&out_opts, "chunked_post", "0", 0);	
        ret = avio_open2(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE|AVIO_FLAG_NONBLOCK, NULL, &out_opts);

        if (ret < 0) {
            fprintf(stderr, "Could not open output file '%s'", out_filename);
            goto end;
        }
    }

    ret = ofmt_ctx->pb && do_sff ? sff_write_header(ofmt_ctx) : avformat_write_header(ofmt_ctx, NULL);
    if (ret < 0) {
        fprintf(stderr, "Error occurred when opening output file\n");
        goto end;
    }
	if(ofmt_ctx->pb){
		avio_flush(ofmt_ctx->pb);
	}

    while (1) {
        AVStream *in_stream, *out_stream;
		ret = av_read_frame(ifmt_ctx, &pkt);
        if (ret < 0)
            break;

        in_stream  = ifmt_ctx->streams[pkt.stream_index];
        out_stream = ofmt_ctx->streams[pkt.stream_index];
		
		i = pkt.stream_index;
		if(curr_dts[i] == AV_NOPTS_VALUE && pkt.dts != AV_NOPTS_VALUE){
			first_dts[i] = pkt.dts;
			start_time[i] = av_gettime_relative();
		}
		if(pkt.dts != AV_NOPTS_VALUE){	
			curr_dts[i] = pkt.dts; //us
		}

        /* copy packet */
        pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
        pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
        pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
        pkt.pos = -1;
		
		ret = ofmt_ctx->pb && do_sff ? sff_write_packet(ofmt_ctx, &pkt) : av_interleaved_write_frame(ofmt_ctx, &pkt); 
		if(ofmt_ctx->pb){
			avio_flush(ofmt_ctx->pb);
		}
        if (ret < 0) {
            fprintf(stderr, "Error muxing packet\n");
            break;
        }
        av_free_packet(&pkt);
		++cnt;
		//printf("cnt %d\t", cnt);
		
		do{
			curr_time[i] = av_gettime_relative();
			cmp = av_compare_ts(curr_dts[i] - first_dts[i], in_stream->time_base, 
					curr_time[i] - start_time[i], AV_TIME_BASE_Q); 
			if(!do_rate_emu || cmp <= 0)break;
			
			av_usleep(10000);
		}while(cmp > 0);
		
    }
	
	ofmt_ctx->pb && do_sff ? sff_write_packet(ofmt_ctx, NULL) : av_write_trailer(ofmt_ctx); 
end:

    avformat_close_input(&ifmt_ctx);

    /* close output */
    if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE) && ofmt_ctx->pb){
        avio_close(ofmt_ctx->pb);
		av_dict_free(&out_opts);
	}
    avformat_free_context(ofmt_ctx);

    if (ret < 0 && ret != AVERROR_EOF) {
        fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
        return 1;
    }
	
	printf("end of remux\n");
    return 0;
}