* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define _XOPEN_SOURCE 600
+
#include "config.h"
#include <inttypes.h>
#include <math.h>
#include "libavutil/avstring.h"
#include "libavutil/colorspace.h"
#include "libavutil/pixdesc.h"
+#include "libavcore/imgutils.h"
#include "libavcore/parseutils.h"
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
char filename[1024];
int width, height, xleft, ytop;
- int64_t faulty_pts;
- int64_t faulty_dts;
- int64_t last_dts_for_fault_detection;
- int64_t last_pts_for_fault_detection;
+ PtsCorrectionContext pts_ctx;
#if CONFIG_AVFILTER
AVFilterContext *out_video_filter; ///<the last filter in the video chain
vp = &is->pictq[is->pictq_rindex];
if (vp->bmp) {
#if CONFIG_AVFILTER
- if (vp->picref->pixel_aspect.num == 0)
+ if (vp->picref->video->pixel_aspect.num == 0)
aspect_ratio = 0;
else
- aspect_ratio = av_q2d(vp->picref->pixel_aspect);
+ aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
#else
/* XXX: use variable in the frame */
if (is->audio_st && is->video_st)
av_diff = get_audio_clock(is) - get_video_clock(is);
printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
- get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->faulty_dts, is->faulty_pts);
+ get_master_clock(is), av_diff, FFMAX(is->skip_frames-1, 0), aqsize / 1024, vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
fflush(stdout);
last_time = cur_time;
}
}
}
+static void stream_close(VideoState *is)
+{
+ VideoPicture *vp;
+ int i;
+ /* XXX: use a special url_shutdown call to abort parse cleanly */
+ is->abort_request = 1;
+ SDL_WaitThread(is->parse_tid, NULL);
+ SDL_WaitThread(is->refresh_tid, NULL);
+
+ /* free all pictures */
+ for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
+ vp = &is->pictq[i];
+#if CONFIG_AVFILTER
+ if (vp->picref) {
+ avfilter_unref_buffer(vp->picref);
+ vp->picref = NULL;
+ }
+#endif
+ if (vp->bmp) {
+ SDL_FreeYUVOverlay(vp->bmp);
+ vp->bmp = NULL;
+ }
+ }
+ SDL_DestroyMutex(is->pictq_mutex);
+ SDL_DestroyCond(is->pictq_cond);
+ SDL_DestroyMutex(is->subpq_mutex);
+ SDL_DestroyCond(is->subpq_cond);
+#if !CONFIG_AVFILTER
+ if (is->img_convert_ctx)
+ sws_freeContext(is->img_convert_ctx);
+#endif
+ av_free(is);
+}
+
+static void do_exit(void)
+{
+ if (cur_stream) {
+ stream_close(cur_stream);
+ cur_stream = NULL;
+ }
+ uninit_opts();
+#if CONFIG_AVFILTER
+ avfilter_uninit();
+#endif
+ if (show_status)
+ printf("\n");
+ SDL_Quit();
+ av_log(NULL, AV_LOG_QUIET, "");
+ exit(0);
+}
+
/* allocate a picture (needs to do that in main thread to avoid
potential locking problems */
static void alloc_picture(void *opaque)
vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
SDL_YV12_OVERLAY,
screen);
+ if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
+ /* SDL allocates a buffer smaller than requested if the video
+ * overlay hardware is unable to support the requested size. */
+ fprintf(stderr, "Error: the video system does not support an image\n"
+ "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
+ "to reduce the image size.\n", vp->width, vp->height );
+ do_exit();
+ }
SDL_LockMutex(is->pictq_mutex);
vp->allocated = 1;
is->video_current_pos= -1;
SDL_UnlockMutex(is->pictq_mutex);
- is->last_dts_for_fault_detection=
- is->last_pts_for_fault_detection= INT64_MIN;
+ 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;
pkt);
if (got_picture) {
- if(pkt->dts != AV_NOPTS_VALUE){
- is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;
- is->last_dts_for_fault_detection= pkt->dts;
+ 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;
}
- if(frame->reordered_opaque != AV_NOPTS_VALUE){
- is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;
- is->last_pts_for_fault_detection= frame->reordered_opaque;
+
+ if (*pts == AV_NOPTS_VALUE) {
+ *pts = 0;
}
}
- if( ( decoder_reorder_pts==1
- || (decoder_reorder_pts && is->faulty_pts<is->faulty_dts)
- || pkt->dts == AV_NOPTS_VALUE)
- && frame->reordered_opaque != AV_NOPTS_VALUE)
- *pts= frame->reordered_opaque;
- else if(pkt->dts != AV_NOPTS_VALUE)
- *pts= pkt->dts;
- else
- *pts= 0;
-
// if (len1 < 0)
// break;
if (got_picture){
if(!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h)))
return -1;
- ref->w = codec->width;
- ref->h = codec->height;
+ ref->video->w = codec->width;
+ ref->video->h = codec->height;
for(i = 0; i < 4; i ++) {
unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0;
unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0;
return codec->get_buffer(codec, pic);
}
- if ((codec->width != ref->w) || (codec->height != ref->h) ||
+ if ((codec->width != ref->video->w) || (codec->height != ref->video->h) ||
(codec->pix_fmt != ref->format)) {
av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n");
return -1;
picref = avfilter_ref_buffer(priv->frame->opaque, ~0);
} else {
picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h);
- av_picture_copy((AVPicture *)&picref->data, (AVPicture *)priv->frame,
- picref->format, link->w, link->h);
+ av_image_copy(picref->data, picref->linesize,
+ priv->frame->data, priv->frame->linesize,
+ picref->format, link->w, link->h);
}
av_free_packet(&pkt);
picref->pts = pts;
picref->pos = pkt.pos;
- picref->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
+ picref->video->pixel_aspect = priv->is->video_st->codec->sample_aspect_ratio;
avfilter_start_frame(link, picref);
avfilter_draw_slice(link, 0, link->h, 1);
avfilter_end_frame(link);
if(avfilter_request_frame(ctx->inputs[0]))
return -1;
- if(!(pic = ctx->inputs[0]->cur_pic))
+ if(!(pic = ctx->inputs[0]->cur_buf))
return -1;
- ctx->inputs[0]->cur_pic = NULL;
+ ctx->inputs[0]->cur_buf = NULL;
frame->opaque = pic;
*pts = pic->pts;
snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
graph->scale_sws_opts = av_strdup(sws_flags_str);
- if(!(filt_src = avfilter_open(&input_filter, "src"))) goto the_end;
- if(!(filt_out = avfilter_open(&output_filter, "out"))) goto the_end;
+ if (avfilter_open(&filt_src, &input_filter, "src") < 0) goto the_end;
+ if (avfilter_open(&filt_out, &output_filter, "out") < 0) goto the_end;
if(avfilter_init_filter(filt_src, NULL, is)) goto the_end;
if(avfilter_init_filter(filt_out, NULL, frame)) goto the_end;
avctx->error_concealment= error_concealment;
avcodec_thread_init(avctx, thread_count);
- set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0);
+ set_context_opts(avctx, avcodec_opts[avctx->codec_type], 0, codec);
if (!codec ||
avcodec_open(avctx, codec) < 0)
ap->time_base= (AVRational){1, 25};
ap->pix_fmt = frame_pix_fmt;
- set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM);
+ set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);
err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
if (err < 0) {
return is;
}
-static void stream_close(VideoState *is)
-{
- VideoPicture *vp;
- int i;
- /* XXX: use a special url_shutdown call to abort parse cleanly */
- is->abort_request = 1;
- SDL_WaitThread(is->parse_tid, NULL);
- SDL_WaitThread(is->refresh_tid, NULL);
-
- /* free all pictures */
- for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
- vp = &is->pictq[i];
-#if CONFIG_AVFILTER
- if (vp->picref) {
- avfilter_unref_buffer(vp->picref);
- vp->picref = NULL;
- }
-#endif
- if (vp->bmp) {
- SDL_FreeYUVOverlay(vp->bmp);
- vp->bmp = NULL;
- }
- }
- SDL_DestroyMutex(is->pictq_mutex);
- SDL_DestroyCond(is->pictq_cond);
- SDL_DestroyMutex(is->subpq_mutex);
- SDL_DestroyCond(is->subpq_cond);
-#if !CONFIG_AVFILTER
- if (is->img_convert_ctx)
- sws_freeContext(is->img_convert_ctx);
-#endif
- av_free(is);
-}
-
static void stream_cycle_channel(VideoState *is, int codec_type)
{
AVFormatContext *ic = is->ic;
step = 1;
}
-static void do_exit(void)
-{
- int i;
- if (cur_stream) {
- stream_close(cur_stream);
- cur_stream = NULL;
- }
- for (i = 0; i < AVMEDIA_TYPE_NB; i++)
- av_free(avcodec_opts[i]);
- av_free(avformat_opts);
- av_free(sws_opts);
-#if CONFIG_AVFILTER
- avfilter_uninit();
-#endif
- if (show_status)
- printf("\n");
- SDL_Quit();
- exit(0);
-}
-
static void toggle_audio_display(void)
{
if (cur_stream) {
static void show_help(void)
{
+ av_log_set_callback(log_callback_help);
show_usage();
show_help_options(options, "Main options:\n",
OPT_EXPERT, 0);
show_help_options(options, "\nAdvanced options:\n",
OPT_EXPERT, OPT_EXPERT);
+ printf("\n");
+ av_opt_show2(avcodec_opts[0], NULL,
+ AV_OPT_FLAG_DECODING_PARAM, 0);
+ printf("\n");
+ av_opt_show2(avformat_opts, NULL,
+ AV_OPT_FLAG_DECODING_PARAM, 0);
+#if !CONFIG_AVFILTER
+ printf("\n");
+ av_opt_show2(sws_opts, NULL,
+ AV_OPT_FLAG_ENCODING_PARAM, 0);
+#endif
printf("\nWhile playing:\n"
"q, ESC quit\n"
"f toggle full screen\n"
/* Called from the main */
int main(int argc, char **argv)
{
- int flags, i;
+ int flags;
+
+ av_log_set_flags(AV_LOG_SKIP_REPEATED);
/* register all codecs, demux and protocols */
avcodec_register_all();
#endif
av_register_all();
- for(i=0; i<AVMEDIA_TYPE_NB; i++){
- avcodec_opts[i]= avcodec_alloc_context2(i);
- }
- avformat_opts = avformat_alloc_context();
-#if !CONFIG_AVFILTER
- sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
-#endif
+ init_opts();
show_banner();