コード例 #1
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
static int dt_transport_event (event_t * event, dt_server_mgt_t * mgt)
{
    dt_lock (&mgt->server_lock);
    event_server_t *entry = mgt->server;

    int ret = 0;
    while (entry->id != event->server_id)
    {
        entry = entry->next;
        if (!entry)
            break;
    }

    if (!entry)
    {
        dt_error (TAG, "Could not found server for:%d \n ", event->server_id);
        ret = -1;
        goto FAIL;
    }

    ret = dt_add_event (event, entry);
    if (ret < 0)                //we need to free this event
    {
        dt_error (TAG, "we can not transport this event, id:%d type:%d\n ", event->server_id, event->type);
        free (event);
        ret = -1;
        goto FAIL;
    }
    dt_unlock (&mgt->server_lock);
    return ret;
  FAIL:
    dt_unlock (&mgt->server_lock);
    return ret;
}
コード例 #2
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
int dt_event_server_init ()
{
    pthread_t tid;
    int ret = 0;

    server_mgt.server = NULL;
    server_mgt.server_count = 0;
    server_mgt.exit_flag = 0;
    dt_lock_init (&server_mgt.server_lock, NULL);

    main_server.id = EVENT_SERVER_MAIN;
    strcpy (main_server.name, "SERVER-MAIN");
    main_server.event_count = 0;
    main_server.event = NULL;
    main_server.next = NULL;
    dt_lock_init (&main_server.event_lock, NULL);

    ret = dt_register_server (&main_server);
    if (ret < 0)
    {
        dt_error (TAG, "SERVER REGISTER FAILED \n");
        return -1;
    }

    ret = pthread_create (&tid, NULL, (void *) &event_transport_loop, NULL);
    if (ret != 0)
    {
        dt_error (TAG, "TRANSTROP LOOP CREATE FAILED \n");
        return -1;
    }
    server_mgt.transport_loop_id = tid;
    dt_info (TAG, "TRANSTROP LOOP CREATE OK, TID:%u \n", (unsigned)tid);
    return 0;
}
コード例 #3
0
ファイル: dtplayer_api.c プロジェクト: jih488/dtplayer_c
void *dtplayer_init (dtplayer_para_t * para)
{
    int ret = 0;
    if (!para)
        return NULL;
    player_register_all();
    dtplayer_context_t *dtp_ctx = malloc(sizeof(dtplayer_context_t)); // will free in dtplayer.c
    if (!dtp_ctx)
    {
        dt_error (TAG, "dtplayer context malloc failed \n");
        return NULL;
    }
    memset (dtp_ctx, 0, sizeof (*dtp_ctx));
    memcpy (&dtp_ctx->player_para, para, sizeof (dtplayer_para_t));

    dt_info(TAG,"start playing :%s \n",para->file_name);
    /*init player */
    ret = player_init (dtp_ctx);
    if (ret < 0)
    {
        dt_error (TAG, "PLAYER INIT FAILED \n");
        free(dtp_ctx);
        dtp_ctx = NULL;
    }
    return dtp_ctx;
}
コード例 #4
0
ファイル: dtvideo_api.c プロジェクト: jih488/dtplayer_c
//==Part1:Control
int dtvideo_init (void **video_priv, dtvideo_para_t * para, void *parent)
{
    int ret = 0;
    dtvideo_context_t *vctx = (dtvideo_context_t *) malloc (sizeof (dtvideo_context_t));
    if (!vctx)
    {
        dt_error (TAG, "[%s:%d] video init failed \n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR0;
    }
    memcpy (&vctx->video_para, para, sizeof (dtvideo_para_t));
    vctx->video_para.extradata_size = para->extradata_size;
    memcpy (&(vctx->video_para.extradata[0]), &(para->extradata[0]), para->extradata_size);

    //we need to set parent early
    vctx->parent = parent;
    ret = video_init (vctx);
    if (ret < 0)
    {
        dt_error (TAG, "[%s:%d] dtvideo_mgt_init failed \n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR1;
    }
    *video_priv = (void *) vctx;
    return ret;
  ERR1:
    free (vctx);
  ERR0:
    return ret;
}
コード例 #5
0
ファイル: stream_cache.c プロジェクト: jih488/dtplayer_c
static stream_cache_t * create_cache(int size,float pre)
{
    if(size <= 0)
        goto ERR0;
    
    stream_cache_t *cache = (stream_cache_t *)malloc(sizeof(stream_cache_t));
    if(!cache)
    {
        dt_error(TAG,"cache ctx failed");
        goto ERR0;
    }
    memset(cache,0,sizeof(stream_cache_t));
    cache->data = (uint8_t *)malloc(size);
    if(!cache->data)
    {
        dt_error(TAG,"cache data malloc failed");
        goto ERR1;
    }
    cache->total_size = size;
    cache->fix_pre_size = size * pre;
    //cache->post_size = size * post;

    dt_lock_init (&cache->mutex, NULL);
    dt_info(TAG,"Create cache ok, total:%d fixpresize:%d pre:%f \n",cache->total_size,cache->fix_pre_size,pre);
    return cache;
ERR1:
    free(cache);
ERR0:
    return NULL;
}
コード例 #6
0
ファイル: dthost_api.c プロジェクト: jih488/dtplayer_c
int dthost_init (void **host_priv, dthost_para_t * para)
{
    int ret = 0;
    if (*host_priv)
    {
        dt_error (TAG, "[%s:%d] host_priv is Null\n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR0;
    }
    dthost_context_t *hctx = malloc (sizeof (dthost_context_t));
    if (!hctx)
    {
        dt_info (TAG, "[%s:%d] dthost_context_t malloc failed\n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR0;
    }
    dt_debug (TAG, "hctx :%p \n", hctx);
    memset (hctx, 0, sizeof (dthost_context_t));
    memcpy (&hctx->para, para, sizeof (dthost_para_t));
    ret = host_init (hctx);
    if (ret < 0)
    {
        dt_error (TAG, "[%s:%d] dthost_init failed\n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR1;
    }
    *host_priv = (void *) hctx;
    return ret;
ERR1:
    free (hctx);
ERR0:
    return ret;
}
コード例 #7
0
ファイル: ad_ffmpeg.c プロジェクト: peterfuture/dtplayer_c
//1 get one frame 0 failed -1 err
int ffmpeg_adec_decode(ad_wrapper_t *wrapper, adec_ctrl_t *pinfo)
{
    int got_samples = 0;
    int ret = 0;
    int data_size = 0;
    AVFrame frame_tmp;
    //AVFrame frame;
    AVPacket pkt;
    memset(&pkt, 0, sizeof(AVPacket));
    pkt.data = pinfo->inptr;
    pkt.size = pinfo->inlen;
    pkt.side_data_elems = 0;
    memset(&frame_tmp, 0, sizeof(AVFrame));
    memset(frame, 0, sizeof(AVFrame));

    dtaudio_decoder_t *decoder = (dtaudio_decoder_t *)wrapper->parent;
    dt_debug(TAG, "start decode size:%d %02x %02x \n", pkt.size, pkt.data[0],
             pkt.data[1]);
    ret = avcodec_decode_audio4(avctxp, frame, &got_samples, &pkt);
    dt_debug(TAG, "start decode size:%d %02x %02x %02x %02x \n", pkt.size,
             pkt.data[0], pkt.data[1], pkt.data[2], pkt.data[3]);
    if (ret < 0) {
        dt_error(TAG, "decode failed ret:%d \n", ret);
        goto EXIT;
    }

    if (!got_samples) {         //decode return 0
        dt_error(TAG, "get no samples out \n");
        pinfo->outlen = 0;
        goto EXIT;
    }
    data_size = av_samples_get_buffer_size(frame->linesize, avctxp->channels,
                                           frame->nb_samples, avctxp->sample_fmt, 1);
    if (data_size > 0) {
        audio_convert(decoder, &frame_tmp, frame);
        //out frame too large, realloc out buf
        if (pinfo->outsize < frame_tmp.linesize[0]) {
            pinfo->outptr = realloc(pinfo->outptr, frame_tmp.linesize[0] * 2);
            pinfo->outsize = frame_tmp.linesize[0] * 2;
        }

        memcpy(pinfo->outptr, frame_tmp.data[0], frame_tmp.linesize[0]);
        pinfo->outlen = frame_tmp.linesize[0];
    } else {
        dt_error(TAG, "data_size invalid: size:%d outlen:%d \n", data_size,
                 pinfo->outlen);
        pinfo->outlen = 0;
    }

EXIT:
    if (frame_tmp.data[0]) {
        free(frame_tmp.data[0]);
    }
    frame_tmp.data[0] = NULL;
    return ret;
}
コード例 #8
0
ファイル: dt_log.c プロジェクト: peterfuture/dtplayer_c
int main()
{
    dt_get_log_level();
    dt_info("TEST", "this is info level test \n");
    dt_error("TEST", "this is error level test \n");
    dt_debug("TEST", "this is debug level test \n");
    dt_warning("TEST", "this is warnning level test \n");
    dt_set_log_level(1);
    dt_info("TEST", "this is info level test \n");
    dt_error("TEST", "this is error level test \n");
    dt_debug("TEST", "this is debug level test \n");
    dt_warning("TEST", "this is warning level test \n");
    return;
}
コード例 #9
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
int dt_send_event (event_t * event)
{
    dt_server_mgt_t *mgt = &server_mgt;
    event_server_t *server_hub = mgt->server;
    if (!server_hub)
    {
        dt_error (TAG, "EVENT SEND FAILED \n");
        return -1;
    }
    dt_lock (&server_hub->event_lock);
    if (server_hub->event_count == 0)
        server_hub->event = event;
    else
    {
        event_t *entry = server_hub->event;
        while (entry->next)
            entry = entry->next;
        entry->next = event;

    }
    server_hub->event_count++;
    dt_unlock (&server_hub->event_lock);
    dt_debug (TAG, "EVENT:%d SEND OK, event count:%d \n", event->type, server_hub->event_count);
    return 0;
}
コード例 #10
0
ファイル: demuxer_ffmpeg.c プロジェクト: microcai/dtplayer
static int media_format_convert (const char *name)
{
    int i, j;
    int type = MEDIA_FORMAT_INVALID;
    j = sizeof (media_map) / sizeof (type_map_t);
    for (i = 0; i < j; i++)
    {
        if (strcmp (name, media_map[i].key) == 0)
        {
            break;
        }
    }
    if (i == j)
    {
        for (i = 0; i < j; i++)
        {
            if (strstr (name, media_map[i].key) != NULL)
            {
                break;
            }
            if (i == j)
            {
                dt_error ("Unsupport media type %s\n", name);
                return MEDIA_FORMAT_INVALID;
            }
        }
    }
    type = media_map[i].value;
    dt_info (TAG, "name:%s media_type=%d \n", name, type);
    return type;

}
コード例 #11
0
int audio_output_init(dtaudio_output_t * ao, int ao_id)
{
    int ret = 0;
    pthread_t tid;

    /*select ao device */
    ret = select_ao_device(ao, ao_id);
    if (ret < 0) {
        return -1;
    }

    ao_wrapper_t *wrapper = ao->wrapper;
    memcpy(&wrapper->para, &ao->para, sizeof(dtaudio_para_t));
    wrapper->init(wrapper);
    dt_info(TAG, "[%s:%d] audio output init success\n", __FUNCTION__, __LINE__);

    /*start aout pthread */
    ret = pthread_create(&tid, NULL, audio_output_thread, (void *) ao);
    if (ret != 0) {
        dt_error(TAG, "[%s:%d] create audio output thread failed\n", __FUNCTION__, __LINE__);
        return ret;
    }
    ao->output_thread_pid = tid;
    dt_info(TAG, "[%s:%d] create audio output thread success\n", __FUNCTION__, __LINE__);
    return ret;
}
コード例 #12
0
ファイル: stream_file.c プロジェクト: peterfuture/dtplayer_c
static int stream_file_open(stream_wrapper_t * wrapper, char *stream_name)
{
    int fd = -1;
    file_ctx_t *ctx = malloc(sizeof(*ctx));
    stream_ctrl_t *info = &wrapper->info;
    memset(info, 0, sizeof(*info));
    fd = open(stream_name, O_RDONLY);
    if (fd < 0) {
        dt_error(TAG, "OPEN FILE FAILED \n");
        return -1;
    }
    ctx->fd = fd;

    struct stat state;
    if (stat(stream_name, &state) < 0) {
        ctx->file_size = -1;
    } else {
        ctx->file_size = state.st_size;
    }
    wrapper->stream_priv = (void *)ctx;
    info->stream_size = ctx->file_size;
    info->is_stream = 0;
    info->seek_support = 1;
    info->cur_pos = 0;
    return DTERROR_NONE;
}
コード例 #13
0
ファイル: demuxer_ffmpeg.c プロジェクト: microcai/dtplayer
static int demuxer_ffmpeg_open (demuxer_wrapper_t * wrapper)
{
    AVFormatContext *ic = NULL;
    int err, ret;
    
    dtdemuxer_context_t *ctx = (dtdemuxer_context_t *)wrapper->parent;
    char *file_name = ctx->file_name;

    av_register_all ();
    err = avformat_open_input (&ic, file_name, NULL, NULL);
    if (err < 0)
        return -1;

    dt_info (TAG, "[%s:%d] avformat_open_input ok\n", __FUNCTION__, __LINE__);
    wrapper->demuxer_priv = (void *) ic;

    err = avformat_find_stream_info (ic, NULL);
    if (err < 0)
    {
        dt_error (TAG, "%s: could not find codec parameters\n", file_name);
        ret = -1;
        goto FAIL;
    }

    dt_info (TAG, "[%s:%d] start_time:%lld \n", __FUNCTION__, __LINE__, ic->start_time);
    return 0;
  FAIL:
    avformat_close_input (&ic);
    return ret;
}
コード例 #14
0
ファイル: dtvideo_decoder.c プロジェクト: jih488/dtplayer_c
int video_decoder_init (dtvideo_decoder_t * decoder)
{
    int ret = 0;
    pthread_t tid;
    /*select decoder */
    ret = select_video_decoder (decoder);
    if (ret < 0)
        return -1;

    vd_wrapper_t *wrapper = decoder->wrapper; 
    /*init decoder */
    decoder->pts_current = decoder->pts_first = -1;
    decoder->vd_priv = decoder->para.avctx_priv;
    ret = wrapper->init (decoder);
    if (ret < 0)
        return -1;
    
    pts_mode = 0;    
    char value[512];
    if(GetEnv("VIDEO","pts.mode",value) > 0)
    {
        pts_mode = atoi(value);
        dt_info(TAG,"pts mode:%d fps:%f \n",pts_mode,decoder->para.fps);
    }
    
    dt_info (TAG, "[%s:%d] video decoder init ok\n", __FUNCTION__, __LINE__);
    /*init pcm buffer */
    dtvideo_context_t *vctx = (dtvideo_context_t *) decoder->parent;
    vctx->vo_queue = queue_new ();
    queue_t *picture_queue = vctx->vo_queue;
    if (NULL == picture_queue)
    {
        dt_error (TAG, "create video out queue failed\n");
        return -1;
    }
    /*create thread */
    ret = pthread_create (&tid, NULL, video_decode_loop, (void *) decoder);
    if (ret != 0)
    {
        dt_error (TAG, "create audio decoder thread failed\n");
        return ret;
    }
    decoder->video_decoder_pid = tid;
    video_decoder_start (decoder);
    //decoder->status=ADEC_STATUS_RUNNING;//start decode after init
    return 0;
}
コード例 #15
0
ファイル: vf_ffmpeg.c プロジェクト: peterfuture/dtplayer_c
/***********************************************************************
**
** Process one frame with ffmpeg-libavfilter
**
***********************************************************************/
static int convert_picture(vf_wrapper_t * wrapper, dt_av_frame_t * src)
{
    uint8_t *buffer;
    int buffer_size;

    vf_ffmpeg_ctx_t *vf_ctx = (vf_ffmpeg_ctx_t *)(wrapper->vf_priv);
    dtvideo_para_t *para = &wrapper->para;
    int sw = para->s_width;
    int dw = para->d_width;
    int sh = para->s_height;
    int dh = para->d_height;
    int sf = para->s_pixfmt;
    int df = para->d_pixfmt;

    if (!vf_ctx->swap_frame) {
        vf_ctx->swap_frame = (dt_av_frame_t *)malloc(sizeof(dt_av_frame_t));
    }

    dt_av_frame_t *pict = vf_ctx->swap_frame;
    if (!pict) {
        dt_error(TAG, "[%s:%d] err: swap frame malloc failed \n", __FUNCTION__,
                 __LINE__);
        return -1;
    }
    memset(pict, 0, sizeof(dt_av_frame_t));

    AVPicture *dst = (AVPicture *)pict;
    buffer_size = avpicture_get_size(df, dw, dh);
    if (buffer_size > vf_ctx->swap_buf_size) {
        if (vf_ctx->swapbuf) {
            free(vf_ctx->swapbuf);
        }
        vf_ctx->swap_buf_size = buffer_size;
        vf_ctx->swapbuf = (uint8_t *) malloc(buffer_size * sizeof(uint8_t));
    }
    buffer = vf_ctx->swapbuf;
    avpicture_fill((AVPicture *) dst, buffer, df, dw, dh);

    vf_ctx->pSwsCtx = sws_getCachedContext(vf_ctx->pSwsCtx, sw, sh, sf, dw, dh, df,
                                           SWS_BICUBIC, NULL, NULL, NULL);
    sws_scale(vf_ctx->pSwsCtx, src->data, src->linesize, 0, sh, dst->data,
              dst->linesize);

    pict->pts = src->pts;
    pict->width = dw;
    pict->height = dh;
    pict->pixfmt = df;
    if (src->data) {
        free(src->data[0]);
    }
    memcpy(src, pict, sizeof(dt_av_frame_t));

    vf_ctx->swapbuf = NULL;
    vf_ctx->swap_buf_size = 0;
    return 0;
}
コード例 #16
0
ファイル: dtvideo.c プロジェクト: shihuaxian/dtplayer_c
int video_start (dtvideo_context_t * vctx)
{
    if (vctx->video_status == VIDEO_STATUS_INITED)
    {
        dtvideo_output_t *video_out = &vctx->video_out;
        video_output_start (video_out);
        vctx->video_status = VIDEO_STATUS_ACTIVE;
    }
    else
        dt_error (TAG, "[%s:%d]video output start failed \n", __FUNCTION__, __LINE__);
    return 0;
}
コード例 #17
0
ファイル: dthost_api.c プロジェクト: jih488/dtplayer_c
int dthost_write_frame (void *host_priv, dt_av_pkt_t * frame, int type)
{
    int ret = 0;
    if (!host_priv)
    {
        dt_error (TAG, "[%s:%d] host_priv==NULL \n", __FUNCTION__, __LINE__);
        return -1;
    }
    dthost_context_t *hctx = (dthost_context_t *) (host_priv);
    ret = host_write_frame (hctx, frame, type);
    return ret;
}
コード例 #18
0
ファイル: dthost_api.c プロジェクト: jih488/dtplayer_c
int dthost_get_out_closed (void *host_priv)
{
    int ret = 0;
    if (!host_priv)
    {
        dt_error (TAG, "host PRIV IS NULL \n");
        return -1;
    }
    dthost_context_t *hctx = (dthost_context_t *) host_priv;
    ret = host_get_out_closed (hctx);
    return ret;
}
コード例 #19
0
ファイル: stream_cache.c プロジェクト: jih488/dtplayer_c
static int stream_cache_seek (stream_wrapper_t * wrapper, int64_t pos, int whence)
{
    int ret = 0;
    cache_ctx_t *ctx = (cache_ctx_t *)wrapper->stream_priv;
    stream_cache_t *cache = ctx->cache;
    stream_wrapper_t *real_st = ctx->wrapper;
    stream_ctrl_t *info = &wrapper->info;
    info->eof_flag = 0;
    dt_info(TAG,"Enter cache seek \n");
    // ret stream size
    if(whence == AVSEEK_SIZE)
    {
        dt_debug(TAG,"REQUEST STREAM SIZE:%lld \n",info->stream_size);
        return info->stream_size;
    }
    int step;
    int orig;
    if(whence == SEEK_SET)
    {
        step = abs(info->cur_pos - pos);
        orig = (info->cur_pos > pos)?0:1;
    }
    if(whence == SEEK_CUR)
    {
        step = abs(pos);
        orig = (pos < 0)?0:1;
    }

    if(cache_seek(cache,step,orig) == 0) // seek in cache
    {
        dt_info(TAG,"cache seek success \n");
    }
    else // seek through real stream ops
    {
        pause_cache_thread(ctx);
        ret =real_st->seek(real_st,pos,whence); // fixme: seek maybe failed for online video
        if(ret != DTERROR_NONE)
        {
            dt_error(TAG,"SEEK FAILED \n");
        }
        cache_reset(ctx->cache);
        resume_cache_thread(ctx);
    }

    info->eof_flag = 0;
    if(whence == SEEK_SET)
        info->cur_pos = pos;
    if(whence == SEEK_CUR)
        info->cur_pos += pos;

    return ret;
}
コード例 #20
0
static int select_video_decoder (dtvideo_decoder_t * decoder)
{
    vd_wrapper_t **p;
    p = &g_vd;
    if (!*p)
    {
        dt_error (TAG, "[%s:%d] select no video decoder \n", __FUNCTION__, __LINE__);
        return -1;
    }
    decoder->wrapper = *p;
    dt_info (TAG, "[%s:%d] select--%s video decoder \n", __FUNCTION__, __LINE__, (*p)->name);
    return 0;
}
コード例 #21
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
event_t *dt_alloc_event ()
{
    event_t *event = (event_t *) malloc (sizeof (event_t));
    if (!event)
    {
        dt_error (TAG, "EVENT ALLOC FAILED \n");
        return NULL;
    }
    event->next = NULL;
    event->server_id = -1;
    event->type = -1;
    return event;
}
コード例 #22
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
int dt_send_event_sync (event_t * event)
{
    dt_server_mgt_t *mgt = &server_mgt;
    event_server_t *server_hub = mgt->server;
    if (!server_hub)
    {
        dt_error (TAG, "EVENT SEND FAILED \n");
        return -1;
    }
    dt_transport_event (event, mgt);
    dt_debug (TAG, "EVENT:%d BYPASS SEND OK \n");
    return 0;
}
コード例 #23
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
int dt_register_server (event_server_t * server)
{
    dt_server_mgt_t *mgt = &server_mgt;
    int ret = 0;
    if (!mgt)
    {
        dt_error (TAG, "SERVICE MGT IS NULL\n");
        return -1;
    }
    dt_lock (&mgt->server_lock);
    if (mgt->server_count == 0)
        mgt->server = server;
    event_server_t *entry = mgt->server;
    while (entry->next != NULL)
    {
        if (entry->id == server->id)
        {
            dt_error (TAG, "SERVICE HAS BEEN REGISTERD BEFORE\n");
            ret = -1;
            goto FAIL;
        }
        entry = entry->next;
    }
    if (entry->next == NULL)
    {
        entry->next = server;
        server->next = NULL;
        mgt->server_count++;
    }
    dt_unlock (&mgt->server_lock);
    dt_info (TAG, "SERVICE:%s REGISTER OK,SERVERCOUNT:%d \n", server->name, mgt->server_count);
    return 0;

  FAIL:
    dt_unlock (&mgt->server_lock);
    return ret;

}
コード例 #24
0
ファイル: dtstream.c プロジェクト: jih488/dtplayer_c
int stream_open (dtstream_context_t * stm_ctx)
{
    int ret = 0;
    if (stream_select (stm_ctx) == -1)
    {
        dt_error (TAG, "select stream failed \n");
        return -1;
    }
    stream_wrapper_t *wrapper = stm_ctx->stream;
    memset(&wrapper->info,0,sizeof(stream_ctrl_t));
    dt_info (TAG, "select stream:%s\n", wrapper->name);

    //stream buffer eanble check
    char value[512];
    int cache_enable = 0;
    if(GetEnv("STREAM","stream.cache",value) > 0)
    {
        cache_enable = atoi(value);
        dt_info(TAG,"cache enable:%d \n",cache_enable);
    }
    else
        dt_info(TAG,"cache enable not set, use default:%d \n",cache_enable);
    if(cache_enable)
    {
        extern stream_wrapper_t stream_cache;
        wrapper = &stream_cache;
        wrapper->stream_priv = stm_ctx->stream;
        stm_ctx->stream = wrapper;
    }
    ret = wrapper->open (wrapper, stm_ctx->stream_name);
    if (ret < 0)
    {
        dt_error (TAG, "stream open failed\n");
        return -1;
    }
    dt_info (TAG, "stream open ok\n");
    return 0;
}
コード例 #25
0
ファイル: dtvideo_api.c プロジェクト: jih488/dtplayer_c
int dtvideo_stop (void *video_priv)
{
    int ret;
    dtvideo_context_t *vctx = (dtvideo_context_t *) video_priv;
    if (!vctx)
    {
        dt_error (TAG, "[%s:%d] dt video context == NULL\n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR0;
    }
    ret = video_stop (vctx);
    if (ret < 0)
    {
        dt_error (TAG, "[%s:%d] DTVIDEO STOP FAILED\n", __FUNCTION__, __LINE__);
        ret = -1;
        goto ERR0;
    }
    free (video_priv);
    video_priv = NULL;
    return ret;
  ERR0:
    return ret;

}
コード例 #26
0
ファイル: ad_ffmpeg.c プロジェクト: peterfuture/dtplayer_c
int ffmpeg_adec_init(ad_wrapper_t *wrapper, void *parent)
{
    wrapper->parent = parent;
    dtaudio_decoder_t *decoder = (dtaudio_decoder_t *)parent;
    //select video decoder and call init
    dt_info(TAG, "FFMPEG AUDIO DECODER INIT ENTER\n");
    AVCodec *codec = NULL;
    if (decoder->decoder_priv) {
        avctxp = (AVCodecContext *) decoder->decoder_priv;
    } else {
        avctxp = alloc_ffmpeg_ctx(decoder);
    }
    if (!avctxp) {
        return -1;
    }
    enum AVCodecID id = avctxp->codec_id;
    dt_info(TAG, "[%s:%d] param-- src channel:%d sample:%d id:%d format:%d \n",
            __FUNCTION__, __LINE__, avctxp->channels, avctxp->sample_rate, id,
            decoder->para.afmt);
    dt_info(TAG, "[%s:%d] param-- dst channels:%d samplerate:%d \n", __FUNCTION__,
            __LINE__, decoder->para.dst_channels, decoder->para.dst_samplerate);
    codec = avcodec_find_decoder(id);
    if (NULL == codec) {
        dt_error(TAG, "[%s:%d] video codec find failed \n", __FUNCTION__, __LINE__);
        return -1;
    }

    if (avcodec_open2(avctxp, codec, NULL) < 0) {
        dt_error(TAG, "[%s:%d] video codec open failed \n", __FUNCTION__, __LINE__);
        return -1;
    }
    dt_info(TAG, "[%s:%d] ffmpeg dec init ok \n", __FUNCTION__, __LINE__);
    //alloc one frame for decode
    frame = av_frame_alloc();
    return 0;
}
コード例 #27
0
ファイル: stream_cache.c プロジェクト: jih488/dtplayer_c
static int create_cache_thread (cache_ctx_t * ctx)
{
    pthread_t tid;
    ctx->cache_status = ST_STATUS_IDLE;
    ctx->cache_flag = ST_FLAG_NULL;
    int ret = pthread_create (&tid, NULL, (void *) &cache_thread, (void *)ctx);
    if (ret != 0)
    {
        dt_error (TAG "file:%s [%s:%d] data fill thread crate failed \n", __FILE__, __FUNCTION__, __LINE__);
        return -1;
    }
    ctx->cache_tid = tid;
    ctx->cache_status = ST_STATUS_RUNNING;
    dt_info (TAG, "cache Thread create ok\n");
    return 0;
}
コード例 #28
0
ファイル: dt_event.c プロジェクト: jih488/dtplayer_c
int dt_add_event (event_t * event, event_server_t * server)
{
    event_server_t *server_hub = server;
    if (!server_hub)
    {
        dt_error (TAG, "EVENT SEND FAILED \n");
        return -1;
    }
    dt_lock (&server_hub->event_lock);
    if (server_hub->event_count == 0)
        server_hub->event = event;
    else
    {
        event_t *entry = server_hub->event;
        while (entry->next)
            entry = entry->next;
        entry->next = event;

    }
    server_hub->event_count++;
    dt_unlock (&server_hub->event_lock);
    return 0;
}
コード例 #29
0
ファイル: ao_alsa.c プロジェクト: peterfuture/dtplayer_c
static int ao_alsa_init(dtaudio_output_t *aout, dtaudio_para_t *para)
{
    memcpy(&wrapper->para, para, sizeof(dtaudio_para_t));
    snd_pcm_t *alsa_handle;
    snd_pcm_hw_params_t *alsa_hwparams;
    snd_pcm_sw_params_t *alsa_swparams;
    snd_pcm_uframes_t size;
    snd_pcm_uframes_t boundary;

    alsa_ctx_t *ctx = (alsa_ctx_t *)malloc(sizeof(*ctx));
    if (!ctx) {
        return -1;
    }
    wrapper->ao_priv = ctx;

    int afmt = format_to_alsa(wrapper->para.bps);
    uint32_t channels = wrapper->para.dst_channels;
    uint32_t sr = wrapper->para.dst_samplerate;
    int bytes_per_sample = snd_pcm_format_physical_width(afmt) * channels / 8;

    int err = 0;
    err = snd_pcm_open(&alsa_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        free(ctx);
        wrapper->ao_priv = NULL;
        return -1;
    }

    snd_pcm_hw_params_alloca(&alsa_hwparams);
    snd_pcm_sw_params_alloca(&alsa_swparams);

    err = snd_pcm_hw_params_any(alsa_handle, alsa_hwparams);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    err = snd_pcm_hw_params_set_access(alsa_handle, alsa_hwparams,
                                       SND_PCM_ACCESS_RW_INTERLEAVED);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    err = snd_pcm_hw_params_set_format(alsa_handle, alsa_hwparams, afmt);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    err = snd_pcm_hw_params_set_channels_near(alsa_handle, alsa_hwparams,
            &channels);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    err = snd_pcm_hw_params_set_rate_near(alsa_handle, alsa_hwparams, &sr, NULL);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    err = snd_pcm_hw_params(alsa_handle, alsa_hwparams);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }
    /******************************************************************
     *  Set HW Params Finish
    ******************************************************************/

    /* buffer size means the entire size of alsa pcm buffer size*/
    err = snd_pcm_hw_params_get_buffer_size(alsa_hwparams, &size);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    ctx->buf_size = size * bytes_per_sample;

    /*period size means count processed every interrupt*/
    err = snd_pcm_hw_params_get_period_size(alsa_hwparams, &size, NULL);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }
    ctx->trunk_size = size * bytes_per_sample;

    dt_info(TAG, "outburst: %d, bytes_per_sample: %d, buffersize: %d\n",
            ctx->trunk_size, bytes_per_sample, ctx->buf_size);

    /******************************************************************
    * set sw params
    ******************************************************************/
    err = snd_pcm_sw_params_current(alsa_handle, alsa_swparams);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }
#if SND_LIB_VERSION >= 0x000901
    err = snd_pcm_sw_params_get_boundary(alsa_swparams, &boundary);
#else
    boundary = 0x7fffffff;
#endif
    err = snd_pcm_sw_params_set_start_threshold(alsa_handle, alsa_swparams, size);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }
    err = snd_pcm_sw_params_set_stop_threshold(alsa_handle, alsa_swparams,
            boundary);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }
#if SND_LIB_VERSION >= 0x000901
    err = snd_pcm_sw_params_set_silence_size(alsa_handle, alsa_swparams, boundary);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }
#endif

    err = snd_pcm_sw_params(alsa_handle, alsa_swparams);
    if (err < 0) {
        dt_error(TAG, "%s,%d: %s\n", __func__, __LINE__, snd_strerror(err));
        return -1;
    }

    ctx->pause_support = snd_pcm_hw_params_can_pause(alsa_hwparams);

    //buf size limit
    ctx->buf_threshold = bytes_per_sample * sr * DEFAULT_TIME_SIZE / 1000;
    dt_info(TAG, "alsa audio init ok! outburst:%d thres:%d \n", ctx->trunk_size,
            ctx->buf_threshold);
    ctx->handle = alsa_handle;
    ctx->channels = wrapper->para.dst_channels;
    ctx->bps = wrapper->para.bps;
    ctx->samplerate = wrapper->para.dst_samplerate;
    return 0;
}
コード例 #30
0
static void *audio_decode_loop (void *arg)
{
    int ret;
    dtaudio_decoder_t *decoder = (dtaudio_decoder_t *) arg;
    dtaudio_para_t *para = &decoder->aparam;
    dt_av_frame_t frame;
    ad_wrapper_t *wrapper = decoder->wrapper;
    dtaudio_context_t *actx = (dtaudio_context_t *) decoder->parent;
    dt_buffer_t *out = &actx->audio_decoded_buf;
    int declen, fill_size;
    
    //for some type audio, can not read completly frame 
    uint8_t *frame_data = NULL; // point to frame start
    uint8_t *rest_data = NULL;
    int frame_size = 0;
    int rest_size = 0;

    int used;                   // used size after every decode ops

    adec_ctrl_t *pinfo = &decoder->info;
    memset(pinfo,0,sizeof(*pinfo));
    pinfo->channels = para->channels;
    pinfo->samplerate = para->samplerate;
    pinfo->outptr = malloc(MAX_ONE_FRAME_OUT_SIZE);
    pinfo->outsize = MAX_ONE_FRAME_OUT_SIZE;

    dt_info (TAG, "[%s:%d] AUDIO DECODE START \n", __FUNCTION__, __LINE__);
    do
    {
        //maybe receive exit cmd in idle status, so exit prior to idle
        if (decoder->status == ADEC_STATUS_EXIT) 
        {
            dt_debug (TAG, "[%s:%d] receive decode loop exit cmd \n", __FUNCTION__, __LINE__);
            if (frame_data)
                free (frame_data);
            if (rest_data)
                free (rest_data);
            break;
        }

        if (decoder->status == ADEC_STATUS_IDLE)
        {
            dt_info (TAG, "[%s:%d] Idle status ,please wait \n", __FUNCTION__, __LINE__);
            usleep (100);
            continue;
        }

        /*read frame */
        if (!decoder->parent)
        {
            usleep (10000);
            dt_info (TAG, "[%s:%d] decoder parent is NULL \n", __FUNCTION__, __LINE__);
            continue;
        }
        ret = audio_read_frame (decoder->parent, &frame);
        if (ret < 0 || frame.size <= 0)
        {
            usleep (1000);
            dt_debug (TAG, "[%s:%d] dtaudio decoder loop read frame failed \n", __FUNCTION__, __LINE__);
            continue;
        }
        //read ok,update current pts, clear the buffer size
        if (frame.pts >= 0)
        {
            if (decoder->pts_first == -1)
            {
                if(frame.pts == DT_NOPTS_VALUE)
                    frame.pts = 0;
                decoder->pts_first = pts_exchange (decoder, frame.pts);
                dt_info (TAG, "first frame pts:%lld dts:%lld duration:%d size:%d\n", decoder->pts_first, frame.dts, frame.duration, frame.size);
            }
            decoder->pts_current = pts_exchange (decoder, frame.pts);
            dt_debug (TAG, "pkt pts:%lld current:%lld duration:%d pts_s:%lld dts:%lld buf_size:%d \n", frame.pts, decoder->pts_current, frame.duration, frame.pts / 90000, frame.dts, decoder->pts_buffer_size);
            decoder->pts_last_valid = decoder->pts_current;
            decoder->pts_buffer_size = 0;
        }
        //repack the frame
        if (frame_data)
        {
            free (frame_data);
            frame_data = NULL;
            frame_size = 0;
        }
        if (rest_size)
            frame_data = malloc (frame.size + rest_size);
        else
            frame_data = frame.data;
        if (!frame_data)
        {
            dt_error (TAG, "malloc audio frame failed ,we will lost one frame\n");
            if (rest_data)
                free (rest_data);
            rest_size = 0;
            continue;
        }

        if (rest_size)          // no rest data
        {
            dt_debug (TAG, "left %d byet last time\n", rest_size);
            memcpy (frame_data, rest_data, rest_size);
            free (rest_data);
            rest_data = NULL;
            memcpy (frame_data + rest_size, frame.data, frame.size);
        }

        frame_size = frame.size + rest_size;
        rest_size = 0;
        used = 0;
        declen = 0;

        pinfo->inptr = frame_data;
        pinfo->inlen = frame_size;
        pinfo->outlen = 0; 

        //free pkt
        frame.data = NULL;
        frame.size = 0;

      DECODE_LOOP:
        if (decoder->status == ADEC_STATUS_EXIT)
        {
            dt_info (TAG, "[%s:%d] receive decode loop exit cmd \n", __FUNCTION__, __LINE__);
            if (frame_data)
                free (frame_data);
            break;
        }
        /*decode frame */
        pinfo->consume = declen;
        used = wrapper->decode_frame (wrapper, pinfo);
        if (used < 0)
        {
            decoder->decode_err_cnt++;
            /*
             * if decoder is ffmpeg,do not restore data if decode failed
             * if decoder is not ffmpeg, restore raw stream packet if decode failed
             * */
            if (!strcmp (wrapper->name, "ffmpeg audio decoder"))
            {
                dt_error (TAG, "[%s:%d] ffmpeg failed to decode this frame, just break\n", __FUNCTION__, __LINE__);
                decoder->decode_offset += pinfo->inlen;
            }
            continue;
        }
        else if (used == 0 && pinfo->outlen == 0) // used == 0 && out == 0 means need more data
        {
            //maybe need more data
            rest_data = malloc (pinfo->inlen);
            if (rest_data == NULL)
            {
                dt_error ("[%s:%d] rest_data malloc failed\n", __FUNCTION__, __LINE__);
                rest_size = 0;  //skip this frame
                continue;
            }
            memcpy (rest_data, pinfo->inptr, pinfo->inlen);
            rest_size = pinfo->inlen;
            dt_info (TAG, "Maybe we need more data\n");
            continue;
        }
        declen += used;
        pinfo->inlen -= used;
        decoder->decode_offset += used;
        decoder->pts_cache_size = pinfo->outlen;
        decoder->pts_buffer_size += pinfo->outlen;
        if (pinfo->outlen == 0)      //get no data, maybe first time for init
            dt_info (TAG, "GET NO PCM DECODED OUT,used:%d \n",used);

        fill_size = 0;
      REFILL_BUFFER:
        if (decoder->status == ADEC_STATUS_EXIT)
            goto EXIT;
        /*write pcm */
        if (buf_space (out) < pinfo->outlen)
        {
            dt_debug (TAG, "[%s:%d] output buffer do not left enough space ,space=%d level:%d outsie:%d \n", __FUNCTION__, __LINE__, buf_space (out), buf_level (out), pinfo->outlen);
            usleep (1000);
            goto REFILL_BUFFER;
        }
        ret = buf_put (out, pinfo->outptr + fill_size, pinfo->outlen);
        fill_size += ret;
        pinfo->outlen -= ret;
        decoder->pts_cache_size = pinfo->outlen;
        if (pinfo->outlen > 0)
            goto REFILL_BUFFER;

        if (pinfo->inlen)
            goto DECODE_LOOP;
    }
    while (1);
  EXIT:
    dt_info (TAG, "[file:%s][%s:%d]decoder loop thread exit ok\n", __FILE__, __FUNCTION__, __LINE__);
    /* free adec_ctrl_t buf */
    if(pinfo->outptr)
        free(pinfo->outptr);
    pinfo->outlen = pinfo->outsize = 0;
    pthread_exit (NULL);
    return NULL;
}