X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ffplay.c;h=574ef26d58db429f1d4d42364cbf2fbc87ed2249;hb=d6cfad679a818fec2bad1fc94da937ad1a1d7324;hp=237ba93680fb72ad47addad40f18cc2c8fa0be89;hpb=b09b580b4dc118a1eedceee529614ad0fb4e310a;p=ffmpeg diff --git a/ffplay.c b/ffplay.c index 237ba93680f..574ef26d58d 100644 --- a/ffplay.c +++ b/ffplay.c @@ -18,7 +18,7 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define HAVE_AV_CONFIG_H + #include "avformat.h" #include "swscale.h" @@ -49,6 +49,8 @@ } #endif +#undef exit + //#define DEBUG_SYNC #define MAX_VIDEOQ_SIZE (5 * 256 * 1024) @@ -211,6 +213,7 @@ static enum AVDiscard skip_idct= AVDISCARD_DEFAULT; static enum AVDiscard skip_loop_filter= AVDISCARD_DEFAULT; static int error_resilience = FF_ER_CAREFUL; static int error_concealment = 3; +static int decoder_reorder_pts= 0; /* current context */ static int is_full_screen; @@ -1328,6 +1331,21 @@ static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1) return queue_picture(is, src_frame, pts); } +static uint64_t global_video_pkt_pts= AV_NOPTS_VALUE; + +static int my_get_buffer(struct AVCodecContext *c, AVFrame *pic){ + int ret= avcodec_default_get_buffer(c, pic); + uint64_t *pts= av_malloc(sizeof(uint64_t)); + *pts= global_video_pkt_pts; + pic->opaque= pts; + return ret; +} + +static void my_release_buffer(struct AVCodecContext *c, AVFrame *pic){ + if(pic) av_freep(&pic->opaque); + avcodec_default_release_buffer(c, pic); +} + static int video_thread(void *arg) { VideoState *is = arg; @@ -1350,19 +1368,26 @@ static int video_thread(void *arg) /* NOTE: ipts is the PTS of the _first_ picture beginning in this packet, if any */ - pts = 0; - if (pkt->dts != AV_NOPTS_VALUE) - pts = av_q2d(is->video_st->time_base)*pkt->dts; + global_video_pkt_pts= pkt->pts; + len1 = avcodec_decode_video(is->video_st->codec, + frame, &got_picture, + pkt->data, pkt->size); + + if( (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE) + && frame->opaque && *(uint64_t*)frame->opaque != AV_NOPTS_VALUE) + pts= *(uint64_t*)frame->opaque; + else if(pkt->dts != AV_NOPTS_VALUE) + pts= pkt->dts; + else + pts= 0; + pts *= av_q2d(is->video_st->time_base); - len1 = avcodec_decode_video(is->video_st->codec, - frame, &got_picture, - pkt->data, pkt->size); // if (len1 < 0) // break; - if (got_picture) { - if (output_picture2(is, frame, pts) < 0) - goto the_end; - } + if (got_picture) { + if (output_picture2(is, frame, pts) < 0) + goto the_end; + } av_free_packet(pkt); if (step) if (cur_stream) @@ -1547,7 +1572,7 @@ static int synchronize_audio(VideoState *is, short *samples, } /* decode one audio frame and returns its uncompressed size */ -static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr) +static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size, double *pts_ptr) { AVPacket *pkt = &is->audio_pkt; int n, len1, data_size; @@ -1556,7 +1581,8 @@ static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_pt for(;;) { /* NOTE: the audio packet can contain several frames */ while (is->audio_pkt_size > 0) { - len1 = avcodec_decode_audio(is->audio_st->codec, + data_size = buf_size; + len1 = avcodec_decode_audio2(is->audio_st->codec, (int16_t *)audio_buf, &data_size, is->audio_pkt_data, is->audio_pkt_size); if (len1 < 0) { @@ -1632,7 +1658,7 @@ void sdl_audio_callback(void *opaque, Uint8 *stream, int len) while (len > 0) { if (is->audio_buf_index >= is->audio_buf_size) { - audio_size = audio_decode_frame(is, is->audio_buf, &pts); + audio_size = audio_decode_frame(is, is->audio_buf, sizeof(is->audio_buf), &pts); if (audio_size < 0) { /* if error, just output silence */ is->audio_buf_size = 1024; @@ -1703,10 +1729,8 @@ static int stream_component_open(VideoState *is, int stream_index) if (!codec || avcodec_open(enc, codec) < 0) return -1; -#if defined(HAVE_THREADS) if(thread_count>1) avcodec_thread_init(enc, thread_count); -#endif enc->thread_count= thread_count; switch(enc->codec_type) { case CODEC_TYPE_AUDIO: @@ -1736,6 +1760,9 @@ static int stream_component_open(VideoState *is, int stream_index) packet_queue_init(&is->videoq); is->video_tid = SDL_CreateThread(video_thread, is); + + enc-> get_buffer= my_get_buffer; + enc->release_buffer= my_release_buffer; break; case CODEC_TYPE_SUBTITLE: is->subtitle_stream = stream_index; @@ -1881,7 +1908,7 @@ static int decode_thread(void *arg) goto fail; } is->ic = ic; -#ifdef CONFIG_NETWORK +#ifdef CONFIG_RTSP_DEMUXER use_play = (ic->iformat == &rtsp_demuxer); #else use_play = 0; @@ -1897,7 +1924,7 @@ static int decode_thread(void *arg) ret = -1; goto fail; } - ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end + ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe should not use url_feof() to test for the end } /* if seeking requested, we execute it */ @@ -1968,7 +1995,6 @@ static int decode_thread(void *arg) for(;;) { if (is->abort_request) break; -#ifdef CONFIG_NETWORK if (is->paused != is->last_paused) { is->last_paused = is->paused; if (is->paused) @@ -1976,6 +2002,7 @@ static int decode_thread(void *arg) else av_read_play(ic); } +#ifdef CONFIG_RTSP_DEMUXER if (is->paused && ic->iformat == &rtsp_demuxer) { /* wait 10 ms to avoid trying to get another packet */ /* XXX: horrible */ @@ -2341,7 +2368,7 @@ static void event_loop(void) static void opt_frame_size(const char *arg) { - if (parse_image_size(&frame_width, &frame_height, arg) < 0) { + if (av_parse_video_frame_size(&frame_width, &frame_height, arg) < 0) { fprintf(stderr, "Incorrect frame size\n"); exit(1); } @@ -2351,7 +2378,7 @@ static void opt_frame_size(const char *arg) } } -void opt_width(const char *arg) +static void opt_width(const char *arg) { screen_width = atoi(arg); if(screen_width<=0){ @@ -2360,7 +2387,7 @@ void opt_width(const char *arg) } } -void opt_height(const char *arg) +static void opt_height(const char *arg) { screen_height = atoi(arg); if(screen_height<=0){ @@ -2383,15 +2410,15 @@ static void opt_frame_pix_fmt(const char *arg) frame_pix_fmt = avcodec_get_pix_fmt(arg); } -#ifdef CONFIG_NETWORK -void opt_rtp_tcp(void) +#ifdef CONFIG_RTSP_DEMUXER +static void opt_rtp_tcp(void) { /* only tcp protocol */ rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP); } #endif -void opt_sync(const char *arg) +static void opt_sync(const char *arg) { if (!strcmp(arg, "audio")) av_sync_type = AV_SYNC_AUDIO_MASTER; @@ -2403,7 +2430,7 @@ void opt_sync(const char *arg) show_help(); } -void opt_seek(const char *arg) +static void opt_seek(const char *arg) { start_time = parse_date(arg, 1); } @@ -2447,6 +2474,7 @@ const OptionDef options[] = { { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" }, { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" }, { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" }, + { "drp", OPT_BOOL |OPT_EXPERT, {(void*)&decoder_reorder_pts}, "let decoder reorder pts", ""}, { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" }, { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" }, { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" }, @@ -2454,7 +2482,7 @@ const OptionDef options[] = { { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" }, { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)", "threshold" }, { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" }, -#ifdef CONFIG_NETWORK +#ifdef CONFIG_RTSP_DEMUXER { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" }, #endif { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },