#include "libavutil/avstring.h"
#include "libavutil/colorspace.h"
#include "libavutil/pixdesc.h"
-#include "libavcore/imgutils.h"
-#include "libavcore/parseutils.h"
-#include "libavcore/samplefmt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/samplefmt.h"
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
const char program_name[] = "FFplay";
const int program_birth_year = 2003;
+//#define DEBUG
//#define DEBUG_SYNC
#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
if (aspect_ratio <= 0.0)
aspect_ratio = 1.0;
aspect_ratio *= (float)vp->width / (float)vp->height;
- /* if an active format is indicated, then it overrides the
- mpeg format */
-#if 0
- if (is->video_st->codec->dtg_active_format != is->dtg_active_format) {
- is->dtg_active_format = is->video_st->codec->dtg_active_format;
- printf("dtg_active_format=%d\n", is->dtg_active_format);
- }
-#endif
-#if 0
- switch(is->video_st->codec->dtg_active_format) {
- case FF_DTG_AFD_SAME:
- default:
- /* nothing to do */
- break;
- case FF_DTG_AFD_4_3:
- aspect_ratio = 4.0 / 3.0;
- break;
- case FF_DTG_AFD_16_9:
- aspect_ratio = 16.0 / 9.0;
- break;
- case FF_DTG_AFD_14_9:
- aspect_ratio = 14.0 / 9.0;
- break;
- case FF_DTG_AFD_4_3_SP_14_9:
- aspect_ratio = 14.0 / 9.0;
- break;
- case FF_DTG_AFD_16_9_SP_14_9:
- aspect_ratio = 14.0 / 9.0;
- break;
- case FF_DTG_AFD_SP_4_3:
- aspect_ratio = 4.0 / 3.0;
- break;
- }
-#endif
if (is->subtitle_st)
{
{
VideoState *is= opaque;
while(!is->abort_request){
- SDL_Event event;
- event.type = FF_REFRESH_EVENT;
- event.user.data1 = opaque;
+ SDL_Event event;
+ event.type = FF_REFRESH_EVENT;
+ event.user.data1 = opaque;
if(!is->refresh){
is->refresh=1;
- SDL_PushEvent(&event);
+ SDL_PushEvent(&event);
}
usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000); //FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
}
}
/* display picture */
- video_display(is);
+ if (!display_disable)
+ video_display(is);
/* update queue size and signal for next picture */
if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
than nothing, just to test the implementation */
/* display picture */
- video_display(is);
+ if (!display_disable)
+ video_display(is);
}
if (show_status) {
static int64_t last_time;
{
int len1, got_picture, i;
- if (packet_queue_get(&is->videoq, pkt, 1) < 0)
- return -1;
-
- if(pkt->data == flush_pkt.data){
- avcodec_flush_buffers(is->video_st->codec);
+ if (packet_queue_get(&is->videoq, pkt, 1) < 0)
+ return -1;
- SDL_LockMutex(is->pictq_mutex);
- //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
- for(i=0; i<VIDEO_PICTURE_QUEUE_SIZE; i++){
- is->pictq[i].target_clock= 0;
- }
- while (is->pictq_size && !is->videoq.abort_request) {
- SDL_CondWait(is->pictq_cond, is->pictq_mutex);
- }
- is->video_current_pos= -1;
- SDL_UnlockMutex(is->pictq_mutex);
+ if (pkt->data == flush_pkt.data) {
+ avcodec_flush_buffers(is->video_st->codec);
- init_pts_correction(&is->pts_ctx);
- is->frame_last_pts= AV_NOPTS_VALUE;
- is->frame_last_delay = 0;
- is->frame_timer = (double)av_gettime() / 1000000.0;
- is->skip_frames= 1;
- is->skip_frames_index= 0;
- return 0;
+ SDL_LockMutex(is->pictq_mutex);
+ //Make sure there are no long delay timers (ideally we should just flush the que but thats harder)
+ for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
+ is->pictq[i].target_clock= 0;
+ }
+ while (is->pictq_size && !is->videoq.abort_request) {
+ SDL_CondWait(is->pictq_cond, is->pictq_mutex);
}
+ is->video_current_pos = -1;
+ SDL_UnlockMutex(is->pictq_mutex);
- /* NOTE: ipts is the PTS of the _first_ picture beginning in
- this packet, if any */
- is->video_st->codec->reordered_opaque= pkt->pts;
- len1 = avcodec_decode_video2(is->video_st->codec,
- frame, &got_picture,
- pkt);
+ init_pts_correction(&is->pts_ctx);
+ is->frame_last_pts = AV_NOPTS_VALUE;
+ is->frame_last_delay = 0;
+ is->frame_timer = (double)av_gettime() / 1000000.0;
+ is->skip_frames = 1;
+ is->skip_frames_index = 0;
+ return 0;
+ }
- if (got_picture) {
- if (decoder_reorder_pts == -1) {
- *pts = guess_correct_pts(&is->pts_ctx, frame->reordered_opaque, pkt->dts);
- } else if (decoder_reorder_pts) {
- *pts = frame->reordered_opaque;
- } else {
- *pts = pkt->dts;
- }
+ len1 = avcodec_decode_video2(is->video_st->codec,
+ frame, &got_picture,
+ pkt);
- if (*pts == AV_NOPTS_VALUE) {
- *pts = 0;
- }
+ if (got_picture) {
+ if (decoder_reorder_pts == -1) {
+ *pts = guess_correct_pts(&is->pts_ctx, frame->pkt_pts, frame->pkt_dts);
+ } else if (decoder_reorder_pts) {
+ *pts = frame->pkt_pts;
+ } else {
+ *pts = frame->pkt_dts;
+ }
+
+ if (*pts == AV_NOPTS_VALUE) {
+ *pts = 0;
}
-// if (len1 < 0)
-// break;
- if (got_picture){
is->skip_frames_index += 1;
if(is->skip_frames_index >= is->skip_frames){
is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
int i, w, h, stride[4];
unsigned edge;
+ if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES)
+ perms |= AV_PERM_NEG_LINESIZES;
+
if(pic->buffer_hints & FF_BUFFER_HINTS_VALID) {
if(pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ;
if(pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE;
pic->age = INT_MAX;
pic->type = FF_BUFFER_TYPE_USER;
pic->reordered_opaque = codec->reordered_opaque;
+ if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
+ else pic->pkt_pts = AV_NOPTS_VALUE;
return 0;
}
}
pic->reordered_opaque = codec->reordered_opaque;
+ if(codec->pkt) pic->pkt_pts = codec->pkt->pts;
+ else pic->pkt_pts = AV_NOPTS_VALUE;
return 0;
}
codec->get_buffer = input_get_buffer;
codec->release_buffer = input_release_buffer;
codec->reget_buffer = input_reget_buffer;
+ codec->thread_safe_callbacks = 1;
}
priv->frame = avcodec_alloc_frame();
{ .name = NULL }},
};
-#endif /* CONFIG_AVFILTER */
-
-static int video_thread(void *arg)
+static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
{
- VideoState *is = arg;
- AVFrame *frame= avcodec_alloc_frame();
- int64_t pts_int;
- double pts;
- int ret;
-
-#if CONFIG_AVFILTER
- int64_t pos;
char sws_flags_str[128];
+ int ret;
FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P };
AVFilterContext *filt_src = NULL, *filt_out = NULL;
- AVFilterGraph *graph = avfilter_graph_alloc();
snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
graph->scale_sws_opts = av_strdup(sws_flags_str);
- if (avfilter_open(&filt_src, &input_filter, "src") < 0) goto the_end;
- if (avfilter_open(&filt_out, &ffsink , "out") < 0) goto the_end;
-
- if(avfilter_init_filter(filt_src, NULL, is)) goto the_end;
- if(avfilter_init_filter(filt_out, NULL, &ffsink_ctx)) goto the_end;
-
+ if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
+ NULL, is, graph)) < 0)
+ goto the_end;
+ if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out",
+ NULL, &ffsink_ctx, graph)) < 0)
+ goto the_end;
if(vfilters) {
AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
inputs->pad_idx = 0;
inputs->next = NULL;
- if (avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL) < 0)
+ if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
goto the_end;
av_freep(&vfilters);
} else {
- if(avfilter_link(filt_src, 0, filt_out, 0) < 0) goto the_end;
+ if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0)
+ goto the_end;
}
- avfilter_graph_add_filter(graph, filt_src);
- avfilter_graph_add_filter(graph, filt_out);
- if (avfilter_graph_config(graph, NULL) < 0)
+ if ((ret = avfilter_graph_config(graph, NULL)) < 0)
goto the_end;
is->out_video_filter = filt_out;
+the_end:
+ return ret;
+}
+
+#endif /* CONFIG_AVFILTER */
+
+static int video_thread(void *arg)
+{
+ VideoState *is = arg;
+ AVFrame *frame= avcodec_alloc_frame();
+ int64_t pts_int;
+ double pts;
+ int ret;
+
+#if CONFIG_AVFILTER
+ AVFilterGraph *graph = avfilter_graph_alloc();
+ AVFilterContext *filt_out = NULL;
+ int64_t pos;
+
+ if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
+ goto the_end;
+ filt_out = is->out_video_filter;
#endif
for(;;) {
}
if (av_cmp_q(tb, is->video_st->time_base)) {
- int64_t pts1 = pts_int;
+ av_unused int64_t pts1 = pts_int;
pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
- av_log(NULL, AV_LOG_DEBUG, "video_thread(): "
- "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
- tb.num, tb.den, pts1,
- is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
+ av_dlog(NULL, "video_thread(): "
+ "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
+ tb.num, tb.den, pts1,
+ is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
}
#else
ret = get_video_frame(is, frame, &pts_int, &pkt);
}
the_end:
#if CONFIG_AVFILTER
- avfilter_graph_free(graph);
- av_freep(&graph);
+ avfilter_graph_free(&graph);
#endif
av_free(frame);
return 0;
avctx->skip_loop_filter= skip_loop_filter;
avctx->error_recognition= error_recognition;
avctx->error_concealment= error_concealment;
- avcodec_thread_init(avctx, thread_count);
+ avctx->thread_count= thread_count;
set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0, codec);
AVFormatContext *ic;
int err, i, ret;
int st_index[AVMEDIA_TYPE_NB];
- int st_count[AVMEDIA_TYPE_NB]={0};
- int st_best_packet_count[AVMEDIA_TYPE_NB];
AVPacket pkt1, *pkt = &pkt1;
AVFormatParameters params, *ap = ¶ms;
int eof=0;
ic = avformat_alloc_context();
memset(st_index, -1, sizeof(st_index));
- memset(st_best_packet_count, -1, sizeof(st_best_packet_count));
is->video_stream = -1;
is->audio_stream = -1;
is->subtitle_stream = -1;
}
}
- for(i = 0; i < ic->nb_streams; i++) {
- AVStream *st= ic->streams[i];
- AVCodecContext *avctx = st->codec;
+ for (i = 0; i < ic->nb_streams; i++)
ic->streams[i]->discard = AVDISCARD_ALL;
- if(avctx->codec_type >= (unsigned)AVMEDIA_TYPE_NB)
- continue;
- if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0)
- continue;
-
- if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames)
- continue;
- st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames;
-
- switch(avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (!audio_disable)
- st_index[AVMEDIA_TYPE_AUDIO] = i;
- break;
- case AVMEDIA_TYPE_VIDEO:
- case AVMEDIA_TYPE_SUBTITLE:
- if (!video_disable)
- st_index[avctx->codec_type] = i;
- break;
- default:
- break;
- }
- }
+ if (!video_disable)
+ st_index[AVMEDIA_TYPE_VIDEO] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
+ wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
+ if (!audio_disable)
+ st_index[AVMEDIA_TYPE_AUDIO] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
+ wanted_stream[AVMEDIA_TYPE_AUDIO],
+ st_index[AVMEDIA_TYPE_VIDEO],
+ NULL, 0);
+ if (!video_disable)
+ st_index[AVMEDIA_TYPE_SUBTITLE] =
+ av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
+ wanted_stream[AVMEDIA_TYPE_SUBTITLE],
+ (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
+ st_index[AVMEDIA_TYPE_AUDIO] :
+ st_index[AVMEDIA_TYPE_VIDEO]),
+ NULL, 0);
if (show_status) {
- dump_format(ic, 0, is->filename, 0);
+ av_dump_format(ic, 0, is->filename, 0);
}
/* open the streams */
}else if(cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos>=0){
pos= cur_stream->audio_pkt.pos;
}else
- pos = url_ftell(cur_stream->ic->pb);
+ pos = avio_tell(cur_stream->ic->pb);
if (cur_stream->ic->bit_rate)
incr *= cur_stream->ic->bit_rate / 8.0;
else