/*********************************************************************** ** ** select first sf with capbilities cap ** cap: sf capbilities set ** ***********************************************************************/ static int select_sf(dtsub_filter_t *filter, sf_cap_t cap) { int ret = -1; sf_wrapper_t *sf = g_sf; if (!sf) { return ret; } while (sf != NULL) { if (sf->capable(cap) == cap) { // maybe cap have several elements ret = 0; break; } sf = sf->next; } filter->wrapper = sf; if (sf) { dt_info(TAG, "[%s:%d] %s sub filter selected \n", __FUNCTION__, __LINE__, g_sf->name); } else { dt_info(TAG, "[%s:%d] No sub filter selected \n", __FUNCTION__, __LINE__); } return ret; }
static int select_video_decoder (dtvideo_decoder_t * decoder) { vd_wrapper_t **p; dtvideo_para_t *para = &(decoder->para); p = &g_vd; while(*p != NULL) { if((*p)->vfmt == DT_VIDEO_FORMAT_UNKOWN) break; if((*p)->vfmt == para->vfmt) { if((*p)->is_hw == 1 && (para->flag & DTV_FLAG_DISABLE_OMX) > 0) { dt_info (TAG, "[%s:%d]disable- hw name:%s flag:%d \n", __FUNCTION__, __LINE__,(*p)->name, para->flag); p = &(*p)->next; continue; } break; } p = &(*p)->next; } if(*p == NULL) { dt_info (TAG, "[%s:%d]no valid video decoder found vfmt:%d\n", __FUNCTION__, __LINE__, para->vfmt); return -1; } decoder->wrapper = *p; dt_info (TAG, "[%s:%d] select--%s video decoder \n", __FUNCTION__, __LINE__, (*p)->name); return 0; }
/*********************************************************************** ** ** Init ffmpeg filter ** ***********************************************************************/ static int ffmpeg_vf_init(vf_wrapper_t *wrapper) { int ret = -1; // -1 means not support or no need to process vf_ffmpeg_ctx_t *vf_ctx = (vf_ffmpeg_ctx_t *)malloc(sizeof(vf_ffmpeg_ctx_t)); if (!vf_ctx) { return ret; } memset(vf_ctx, 0, sizeof(*vf_ctx)); dtvideo_para_t *para = &wrapper->para; int sw = para->s_width; int sh = para->s_height; int dw = para->d_width; int dh = para->d_height; int sf = para->s_pixfmt; int df = para->d_pixfmt; vf_ctx->need_process = !(sw == dw && sh == dh && sf == df); dt_info(TAG, "[%s:%d] sw:%d dw:%d sh:%d dh:%d sf:%d df:%d need_process:%d \n", __FUNCTION__, __LINE__, sw, dw, sh, dh, sf, df, vf_ctx->need_process); wrapper->vf_priv = vf_ctx; if (vf_ctx->need_process) { vf_ctx->swap_frame = (dt_av_frame_t *)malloc(sizeof(dt_av_frame_t)); ret = 0; } dt_info(TAG, "[%s:%d] vf init ok\n", __FUNCTION__, __LINE__); return ret; }
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; }
static int stream_ffmpeg_open(stream_wrapper_t * wrapper, char *stream_name) { int ret = 0; const char *filename = stream_name; AVIOContext *ctx = NULL; int64_t size; int dummy; int flags = AVIO_FLAG_READ; stream_ctrl_t *info = &wrapper->info; av_register_all(); avformat_network_init(); if (!strncmp(filename, prefix, strlen(prefix))) { filename += strlen(prefix); } dummy = strncmp(filename, "rtsp:", 5); if (!dummy) { dt_info(TAG, "[ffmpeg] rtsp use ffmpeg inside streamer.\n"); return -1; } dt_info(TAG, "[ffmpeg] Opening %s\n", filename); ret = avio_open(&ctx, filename, flags); if (ret < 0) { dt_info(TAG, "[ffmpeg] Opening %s failed. ret:%d\n", filename, ret); return -1; } wrapper->stream_priv = ctx; size = dummy ? 0 : avio_size(ctx); info->stream_size = size; info->seek_support = ctx->seekable; return DTERROR_NONE; }
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; }
void register_vdec_ext(vd_wrapper_t *vd) { vd_wrapper_t **p; p = &g_vd; while (1) { if (*p == NULL) { break; } dt_info(TAG, "[%s:%d] register vdec: %s comp:%s \n", __FUNCTION__, __LINE__, (*p)->name, vd->name); if (strstr((*p)->name, vd->name) != NULL) { dt_info(TAG, "[%s:%d] vdec already registerd, name:%s fmt:%d \n", __FUNCTION__, __LINE__, (*p)->name, (*p)->vfmt); return; } p = &(*p)->next; } p = &g_vd; if (*p == NULL) { *p = vd; vd->next = NULL; } else { vd->next = *p; *p = vd; } dt_info(TAG, "[%s:%d]register ext vd. vfmt:%d name:%s \n", __FUNCTION__, __LINE__, vd->vfmt, vd->name); }
static void dump_vd_statistics_info(dtvideo_decoder_t * decoder) { vd_statistics_info_t *p_info = &decoder->statistics_info; dt_info(TAG, "==============vd statistics info============== \n"); dt_info(TAG, "DecodedVideoFrameCount: %d\n", p_info->decoded_frame_count); dt_info(TAG, "=================================================== \n"); }
int audio_decoder_init (dtaudio_decoder_t * decoder) { int ret = 0; pthread_t tid; /*select decoder */ ret = select_audio_decoder (decoder); if (ret < 0) { ret = -1; goto ERR0; } /*init decoder */ decoder->pts_current = decoder->pts_first = -1; decoder->decoder_priv = decoder->aparam.avctx_priv; if (decoder->aparam.num == 0 || decoder->aparam.den == 0) decoder->aparam.num = decoder->aparam.den = 1; else dt_info (TAG, "[%s:%d] param: num:%d den:%d\n", __FUNCTION__, __LINE__, decoder->aparam.num, decoder->aparam.den); ad_wrapper_t *wrapper = decoder->wrapper; ret = wrapper->init (wrapper,decoder); if (ret < 0) { ret = -1; goto ERR0; } dt_info (TAG, "[%s:%d] audio decoder init ok\n", __FUNCTION__, __LINE__); /*init pcm buffer */ dtaudio_context_t *actx = (dtaudio_context_t *) decoder->parent; int size = DTAUDIO_PCM_BUF_SIZE; ret = buf_init (&actx->audio_decoded_buf, size); if (ret < 0) { ret = -1; goto ERR1; } /*create thread */ ret = pthread_create (&tid, NULL, audio_decode_loop, (void *) decoder); if (ret != 0) { dt_info (DTAUDIO_LOG_TAG, "create audio decoder thread failed\n"); ret = -1; goto ERR2; } decoder->audio_decoder_pid = tid; audio_decoder_start (decoder); return ret; ERR2: buf_release (&actx->audio_decoded_buf); ERR1: wrapper->release (wrapper); ERR0: return ret; }
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; }
static int ao_alsa_play(dtaudio_output_t *aout, uint8_t * buf, int size) { alsa_ctx_t *ctx = (alsa_ctx_t *)wrapper->ao_priv; snd_pcm_t *alsa_handle = (snd_pcm_t *) ctx->handle; int bytes_per_sample = wrapper->para.bps * wrapper->para.dst_channels / 8; int num_frames = size / bytes_per_sample; snd_pcm_sframes_t res = 0; uint8_t *data = buf; if (!alsa_handle) { return -1; } if (num_frames == 0) { return 0; } if (ao_alsa_level(aout) >= ctx->buf_threshold) { dt_debug(TAG, "ALSA EXCEED THRESHOLD,size:%d thres:%d \n", ao_alsa_level(aout), ctx->buf_threshold); return 0; } res = snd_pcm_writei(alsa_handle, data, num_frames); if (res == -EINTR) { dt_info(TAG, "ALSA HAS NO SPACE, WRITE AGAIN\n"); return res; } if (res == -ESTRPIPE) { snd_pcm_resume(alsa_handle); return res; } if (res == -EBADFD) { snd_pcm_reset(alsa_handle); return res; } if (res < 0) { snd_pcm_prepare(alsa_handle); dt_info(TAG, "snd pcm write failed prepare!\n"); return -1; //goto rewrite; } if (res < num_frames) { data += res * bytes_per_sample; num_frames -= res; //goto rewrite; } return res * bytes_per_sample; }
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; }
static int update_cb (player_state_t * state) { if (state->cur_status == PLAYER_STATUS_EXIT) { dt_info (TAG, "RECEIVE EXIT CMD\n"); ply_ctx.exit_flag = 1; } ply_ctx.cur_time = state->cur_time; ply_ctx.cur_time_ms = state->cur_time_ms; ply_ctx.duration = state->full_time; dt_debug (TAG, "UPDATECB CURSTATUS:%x \n", state->cur_status); dt_info(TAG,"CUR TIME %lld S FULL TIME:%lld \n",state->cur_time,state->full_time); return 0; }
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; }
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; }
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; }
int resume_cache_thread (cache_ctx_t * ctx) { ctx->cache_flag = ST_FLAG_NULL; ctx->cache_status = ST_STATUS_RUNNING; dt_info(TAG,"resume cache thread ok \n"); return 0; }
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; }
/** * This is helper function to get llog directory object. It is used by named * llog operations to find/insert/delete llog entry from llog directory. * * \param[in] env execution environment * \param[in] ctxt llog context * * \retval dt_object of llog directory * \retval ERR_PTR of negative value on error */ struct dt_object *llog_osd_dir_get(const struct lu_env *env, struct llog_ctxt *ctxt) { struct dt_device *dt; struct dt_thread_info *dti = dt_info(env); struct dt_object *dir; int rc; dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt; if (ctxt->loc_dir == NULL) { rc = dt_root_get(env, dt, &dti->dti_fid); if (rc) return ERR_PTR(rc); dir = dt_locate(env, dt, &dti->dti_fid); if (!IS_ERR(dir) && !dt_try_as_dir(env, dir)) { lu_object_put(env, &dir->do_lu); return ERR_PTR(-ENOTDIR); } } else { lu_object_get(&ctxt->loc_dir->do_lu); dir = ctxt->loc_dir; } return dir; }
static int stream_ffmpeg_open (stream_wrapper_t * wrapper,char *stream_name) { const char *filename = stream_name; AVIOContext *ctx = NULL; int64_t size; int dummy; int flags = AVIO_FLAG_READ; stream_ctrl_t *info = &wrapper->info; av_register_all(); avformat_network_init(); if (!strncmp(filename, prefix, strlen(prefix))) filename += strlen(prefix); dummy = !strncmp(filename, "rtsp:", 5); dt_info(TAG, "[ffmpeg] Opening %s\n", filename); if (!dummy && avio_open(&ctx, filename, flags) < 0) return -1; wrapper->stream_priv = ctx; size = dummy ? 0 : avio_size(ctx); info->stream_size = size; info->seek_support = ctx->seekable; return DTERROR_NONE; }
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; }
/*********************************************************************** ** ** capability check ** ***********************************************************************/ static int ffmpeg_vf_capable(vf_cap_t cap) { int ffmpeg_cap = VF_CAP_COLORSPACE_CONVERT | VF_CAP_CLIP; dt_info(TAG, "request cap: %x , %s support:%x \n", cap, "ffmpeg vf", ffmpeg_cap); return cap & ffmpeg_cap; }
static int ao_alsa_resume(dtaudio_output_t *aout) { alsa_ctx_t *ctx = (alsa_ctx_t *)wrapper->ao_priv; snd_pcm_t *handle = (snd_pcm_t *) ctx->handle; int ret = 0; if (ctx->pause_support == 1) { ret = snd_pcm_pause(handle, 0); dt_info(TAG, "ALSA PAUSED SUPPORT RESUME DIRECTLY ret:%d status:%d \n", ret, snd_pcm_state(handle)); } else { snd_pcm_prepare(handle); } dt_info(TAG, "ALSA RESUME \n"); return 0; }
/*********************************************************************** ** ** Process one frame ** ***********************************************************************/ static int ffmpeg_vf_process(vf_wrapper_t *wrapper, dt_av_frame_t *frame) { vf_ffmpeg_ctx_t *vf_ctx = (vf_ffmpeg_ctx_t *)(wrapper->vf_priv); if (vf_ctx->need_process == 0) { dt_info(TAG, "[%s:%d] no need to process but called \n", __FUNCTION__, __LINE__); return 0; } int ret = convert_picture(wrapper, frame); if (ret < 0) { dt_info(TAG, "[%s:%d] vf process failed \n", __FUNCTION__, __LINE__); } return ret; }
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; }
int video_init (dtvideo_context_t * vctx) { int ret = 0; dt_info (TAG, "[%s:%d] dtvideo_mgt start init\n", __FUNCTION__, __LINE__); //call init vctx->video_status = VIDEO_STATUS_INITING; vctx->current_pts = vctx->last_valid_pts = -1; dtvideo_decoder_t *video_dec = &vctx->video_dec; dtvideo_filter_t *video_filt = &vctx->video_filt; dtvideo_output_t *video_out = &vctx->video_out; //vf ctx init //vf will init in vd but used in vo memset (video_filt, 0, sizeof (dtvideo_filter_t)); memcpy (&video_filt->para, &vctx->video_para, sizeof (dtvideo_para_t)); video_filt->parent = vctx; //vd ctx init memset (video_dec, 0, sizeof (dtvideo_decoder_t)); memcpy (&video_dec->para, &vctx->video_para, sizeof (dtvideo_para_t)); video_dec->parent = vctx; ret = video_decoder_init (video_dec); if (ret < 0) goto err1; dt_info (TAG, "[%s:%d] vdecoder init ok\n", __FUNCTION__, __LINE__); //vo ctx init memset (video_out, 0, sizeof (dtvideo_output_t)); memcpy (&(video_out->para), &(vctx->video_para), sizeof (dtvideo_para_t)); video_out->parent = vctx; ret = video_output_init (video_out, vctx->video_para.video_output); if (ret < 0) goto err2; vctx->video_status = VIDEO_STATUS_INITED; dt_info (TAG, "dtvideo init ok,status:%d \n", vctx->video_status); return 0; err1: dt_info (TAG, "[%s:%d]video decoder init failed \n", __FUNCTION__, __LINE__); return -1; err2: video_decoder_stop (video_dec); dt_info (TAG, "[%s:%d]video output init failed \n", __FUNCTION__, __LINE__); return -3; }
int pause_cache_thread (cache_ctx_t * ctx) { ctx->cache_flag = ST_FLAG_PAUSE; while (ctx->cache_status != ST_STATUS_IDLE) usleep (100); ctx->cache_flag = ST_FLAG_NULL; dt_info(TAG,"pause cache thread ok \n"); return 0; }
static void register_vdec (vd_wrapper_t * vd) { vd_wrapper_t **p; p = &g_vd; while (*p != NULL) p = &(*p)->next; *p = vd; dt_info (TAG, "[%s:%d] register vdec, name:%s fmt:%d \n", __FUNCTION__, __LINE__, (*p)->name, (*p)->vfmt); vd->next = NULL; }
static void register_adec (ad_wrapper_t * adec) { ad_wrapper_t **p; p = &g_ad; while (*p != NULL) p = &(*p)->next; *p = adec; dt_info (TAG, "[%s:%d] register adec, name:%s fmt:%d \n", __FUNCTION__, __LINE__, (*p)->name, (*p)->afmt); adec->next = NULL; }
static int demuxer_ffmpeg_seek_frame (demuxer_wrapper_t * wrapper, int timestamp) { AVFormatContext *ic = (AVFormatContext *) wrapper->demuxer_priv; int seek_flags = AVSEEK_FLAG_ANY; int64_t seek_target = timestamp * 1000000; int64_t seek_min = (seek_target > 0) ? seek_target - timestamp + 2 : INT64_MIN; int64_t seek_max = (seek_target < 0) ? seek_target - timestamp - 2 : INT64_MAX; int64_t ret = avformat_seek_file (ic, -1, seek_min, seek_target, seek_max, seek_flags); if (ret >= 0) { dt_info (TAG, "AV_FORMAT_SEEK_FILE OK \n"); return 0; } dt_info (TAG, "AV_FORMAT_SEEK_FILE FAIL \n"); return -1; }