[FFmpeg-cvslog] avcodec/cuvid: set width and height before calling get_format

2017-02-14 Thread Timo Rothenpieler
ffmpeg | branch: master | Timo Rothenpieler  | Tue Feb 
14 11:47:08 2017 +0100| [ce79410bba776d4121685654056f2b4e39bbd3f7] | committer: 
Timo Rothenpieler

avcodec/cuvid: set width and height before calling get_format

The external hw_frames_ctx is initialized in that callback, and needs
that information to be accurate.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ce79410bba776d4121685654056f2b4e39bbd3f7
---

 libavcodec/cuvid.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
index 2a305ab..5e6e716 100644
--- a/libavcodec/cuvid.c
+++ b/libavcodec/cuvid.c
@@ -113,6 +113,10 @@ static int CUDAAPI cuvid_handle_video_sequence(void 
*opaque, CUVIDEOFORMAT* form
 
 ctx->internal_error = 0;
 
+// width and height need to be set before calling ff_get_format
+avctx->width = format->display_area.right;
+avctx->height = format->display_area.bottom;
+
 switch (format->bit_depth_luma_minus8) {
 case 0: // 8-bit
 pix_fmts[1] = AV_PIX_FMT_NV12;
@@ -156,9 +160,6 @@ static int CUDAAPI cuvid_handle_video_sequence(void 
*opaque, CUVIDEOFORMAT* form
 hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
 }
 
-avctx->width = format->display_area.right;
-avctx->height = format->display_area.bottom;
-
 ff_set_sar(avctx, av_div_q(
 (AVRational){ format->display_aspect_ratio.x, 
format->display_aspect_ratio.y },
 (AVRational){ avctx->width, avctx->height }));

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog


[FFmpeg-cvslog] avcodec/cuvid: add format mismatch debug logs

2017-02-14 Thread Timo Rothenpieler
ffmpeg | branch: master | Timo Rothenpieler  | Thu Feb  
9 22:19:59 2017 +0100| [b6f4f0b14b0f8c00d7d1dec1d1f03d82b85dd617] | committer: 
Timo Rothenpieler

avcodec/cuvid: add format mismatch debug logs

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b6f4f0b14b0f8c00d7d1dec1d1f03d82b85dd617
---

 libavcodec/cuvid.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
index 5e6e716..f5a49ce 100644
--- a/libavcodec/cuvid.c
+++ b/libavcodec/cuvid.c
@@ -207,6 +207,11 @@ static int CUDAAPI cuvid_handle_video_sequence(void 
*opaque, CUVIDEOFORMAT* form
 hwframe_ctx->format != AV_PIX_FMT_CUDA ||
 hwframe_ctx->sw_format != avctx->sw_pix_fmt)) {
 av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized 
with incompatible parameters\n");
+av_log(avctx, AV_LOG_DEBUG, "width: %d <-> %d\n", hwframe_ctx->width, 
avctx->width);
+av_log(avctx, AV_LOG_DEBUG, "height: %d <-> %d\n", 
hwframe_ctx->height, avctx->height);
+av_log(avctx, AV_LOG_DEBUG, "format: %s <-> cuda\n", 
av_get_pix_fmt_name(hwframe_ctx->format));
+av_log(avctx, AV_LOG_DEBUG, "sw_format: %s <-> %s\n",
+   av_get_pix_fmt_name(hwframe_ctx->sw_format), 
av_get_pix_fmt_name(avctx->sw_pix_fmt));
 ctx->internal_error = AVERROR(EINVAL);
 return 0;
 }

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog


[FFmpeg-cvslog] avcodec/cuvid: update hw_frames_ctx reference after get_format call

2017-02-14 Thread Timo Rothenpieler
ffmpeg | branch: master | Timo Rothenpieler  | Thu Feb  
9 22:29:47 2017 +0100| [b7d480f4312c5ce7d8ce2f6eb7189f0d96ad5bde] | committer: 
Timo Rothenpieler

avcodec/cuvid: update hw_frames_ctx reference after get_format call

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b7d480f4312c5ce7d8ce2f6eb7189f0d96ad5bde
---

 libavcodec/cuvid.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libavcodec/cuvid.c b/libavcodec/cuvid.c
index 9b35476..2a305ab 100644
--- a/libavcodec/cuvid.c
+++ b/libavcodec/cuvid.c
@@ -143,6 +143,19 @@ static int CUDAAPI cuvid_handle_video_sequence(void 
*opaque, CUVIDEOFORMAT* form
 
 avctx->pix_fmt = surface_fmt;
 
+// Update our hwframe ctx, as the get_format callback might have refreshed 
it!
+if (avctx->hw_frames_ctx) {
+av_buffer_unref(&ctx->hwframe);
+
+ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
+if (!ctx->hwframe) {
+ctx->internal_error = AVERROR(ENOMEM);
+return 0;
+}
+
+hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
+}
+
 avctx->width = format->display_area.right;
 avctx->height = format->display_area.bottom;
 

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog


[FFmpeg-cvslog] avcodec/nvenc: push cuda context before encoding a frame

2017-02-14 Thread Timo Rothenpieler
ffmpeg | branch: master | Timo Rothenpieler  | Mon Feb 
13 22:59:46 2017 +0100| [be74ba648cf4063c9805ebe95ee83fd7299f7fd5] | committer: 
Timo Rothenpieler

avcodec/nvenc: push cuda context before encoding a frame

Thanks to Miroslav Slugeň for figuring out what was going on here.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=be74ba648cf4063c9805ebe95ee83fd7299f7fd5
---

 libavcodec/nvenc.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 51e794e..ba2647b 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1649,6 +1649,8 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket 
*pkt,
   const AVFrame *frame, int *got_packet)
 {
 NVENCSTATUS nv_status;
+CUresult cu_res;
+CUcontext dummy;
 NvencSurface *tmpoutsurf, *inSurf;
 int res;
 
@@ -1666,7 +1668,20 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
 return AVERROR_BUG;
 }
 
+cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context);
+if (cu_res != CUDA_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n");
+return AVERROR_EXTERNAL;
+}
+
 res = nvenc_upload_frame(avctx, frame, inSurf);
+
+cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy);
+if (cu_res != CUDA_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");
+return AVERROR_EXTERNAL;
+}
+
 if (res) {
 inSurf->lockCount = 0;
 return res;
@@ -1702,7 +1717,20 @@ int ff_nvenc_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
 pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
 }
 
+cu_res = dl_fn->cuda_dl->cuCtxPushCurrent(ctx->cu_context);
+if (cu_res != CUDA_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "cuCtxPushCurrent failed\n");
+return AVERROR_EXTERNAL;
+}
+
 nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
+
+cu_res = dl_fn->cuda_dl->cuCtxPopCurrent(&dummy);
+if (cu_res != CUDA_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "cuCtxPopCurrent failed\n");
+return AVERROR_EXTERNAL;
+}
+
 if (nv_status != NV_ENC_SUCCESS &&
 nv_status != NV_ENC_ERR_NEED_MORE_INPUT)
 return nvenc_print_error(avctx, nv_status, "EncodePicture failed!");

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog


[FFmpeg-cvslog] HTTP: improve performance by reducing forward seeks

2017-02-14 Thread Joel Cunningham
ffmpeg | branch: master | Joel Cunningham  | Mon Jan 30 
10:00:44 2017 -0600| [8c8e5d5286bf598a89ef9993a2cf6ea409d03a32] | committer: 
Michael Niedermayer

HTTP: improve performance by reducing forward seeks

This commit optimizes HTTP performance by reducing forward seeks, instead
favoring a read-ahead and discard on the current connection (referred to
as a short seek) for seeks that are within a TCP window's worth of data.
This improves performance because with TCP flow control, a window's worth
of data will be in the local socket buffer already or in-flight from the
sender once congestion control on the sender is fully utilizing the window.

Note: this approach doesn't attempt to differentiate from a newly opened
connection which may not be fully utilizing the window due to congestion
control vs one that is. The receiver can't get at this information, so we
assume worst case; that full window is in use (we did advertise it after all)
and that data could be in-flight

The previous behavior of closing the connection, then opening a new
with a new HTTP range value results in a massive amounts of discarded
and re-sent data when large TCP windows are used.  This has been observed
on MacOS/iOS which starts with an initial window of 256KB and grows up to
1MB depending on the bandwidth-product delay.

When seeking within a window's worth of data and we close the connection,
then open a new one within the same window's worth of data, we discard
from the current offset till the end of the window.  Then on the new
connection the server ends up re-sending the previous data from new
offset till the end of old window.

Example (assumes full window utilization):

TCP window size: 64KB
Position: 32KB
Forward seek position: 40KB

  *  (Next window)
32KB |--| 96KB |---| 160KB
*
  40KB |---| 104KB

Re-sent amount: 96KB - 40KB = 56KB

For a real world test example, I have MP4 file of ~25MB, which ffplay
only reads ~16MB and performs 177 seeks. With current ffmpeg, this results
in 177 HTTP GETs and ~73MB worth of TCP data communication.  With this
patch, ffmpeg issues 4 HTTP GETs and 3 seeks for a total of ~22MB of TCP data
communication.

To support this feature, the short seek logic in avio_seek() has been
extended to call a function to get the short seek threshold value.  This
callback has been plumbed to the URLProtocol structure, which now has
infrastructure in HTTP and TCP to get the underlying receiver window size
via SO_RCVBUF.  If the underlying URL and protocol don't support returning
a short seek threshold, the default s->short_seek_threshold is used

This feature has been tested on Windows 7 and MacOS/iOS.  Windows support
is slightly complicated by the fact that when TCP window auto-tuning is
enabled, SO_RCVBUF doesn't report the real window size, but it does if
SO_RCVBUF was manually set (disabling auto-tuning). So we can only use
this optimization on Windows in the later case

Signed-off-by: Joel Cunningham 
Signed-off-by: Michael Niedermayer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8c8e5d5286bf598a89ef9993a2cf6ea409d03a32
---

 libavformat/avio.c|  7 +++
 libavformat/avio.h|  6 ++
 libavformat/aviobuf.c | 19 ++-
 libavformat/http.c|  8 
 libavformat/tcp.c | 21 +
 libavformat/url.h |  8 
 6 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index 3606eb0..62233a6 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -645,6 +645,13 @@ int ffurl_get_multi_file_handle(URLContext *h, int 
**handles, int *numhandles)
 return h->prot->url_get_multi_file_handle(h, handles, numhandles);
 }
 
+int ffurl_get_short_seek(URLContext *h)
+{
+if (!h->prot->url_get_short_seek)
+return AVERROR(ENOSYS);
+return h->prot->url_get_short_seek(h);
+}
+
 int ffurl_shutdown(URLContext *h, int flags)
 {
 if (!h->prot->url_shutdown)
diff --git a/libavformat/avio.h b/libavformat/avio.h
index e2cb4af..8040094 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -313,6 +313,12 @@ typedef struct AVIOContext {
  */
 enum AVIODataMarkerType current_type;
 int64_t last_time;
+
+/**
+ * A callback that is used instead of short_seek_threshold.
+ * This is current internal only, do not use from outside.
+ */
+int (*short_seek_get)(void *opaque);
 } AVIOContext;
 
 /**
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index bf7e5f8..4ade4d0 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -119,6 +119,7 @@ int ffio_init_context(AVIOContext *s,
 s->ignore_boundary_point = 0;
 s->current_type  = AVIO_DATA_MARKER_UNKNOWN;
 s->last_time = AV_NOPTS_VALUE;
+s->short_seek_get= NULL;
 
 return 0;
 }
@@ -233,6 +234,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int 
whence)
 int64_t pos;
 

[FFmpeg-cvslog] avcodec/hevc_parser: export framerate, remove one dependency on the decoder

2017-02-14 Thread Michael Niedermayer
ffmpeg | branch: master | Michael Niedermayer  | Tue 
Feb 14 16:33:53 2017 +0100| [db3507a670aec46fd5ed58c90d2927eb7f72d8ed] | 
committer: Michael Niedermayer

avcodec/hevc_parser: export framerate, remove one dependency on the decoder

Fixes Ticket6090

Signed-off-by: Michael Niedermayer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=db3507a670aec46fd5ed58c90d2927eb7f72d8ed
---

 libavcodec/hevc_parser.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 508f22f..3546048 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -230,6 +230,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, 
const uint8_t *buf,
 for (;;) {
 int src_length, consumed;
 int ret;
+int num = 0, den = 0;
 buf = avpriv_find_start_code(buf, buf_end, &state);
 if (--buf + 2 >= buf_end)
 break;
@@ -320,6 +321,18 @@ static inline int parse_nal_units(AVCodecParserContext *s, 
const uint8_t *buf,
 avctx->profile  = ps->sps->ptl.general_ptl.profile_idc;
 avctx->level= ps->sps->ptl.general_ptl.level_idc;
 
+if (ps->vps->vps_timing_info_present_flag) {
+num = ps->vps->vps_num_units_in_tick;
+den = ps->vps->vps_time_scale;
+} else if (ps->sps->vui.vui_timing_info_present_flag) {
+num = ps->sps->vui.vui_num_units_in_tick;
+den = ps->sps->vui.vui_time_scale;
+}
+
+if (num != 0 && den != 0)
+av_reduce(&avctx->framerate.den, &avctx->framerate.num,
+  num, den, 1 << 30);
+
 if (!sh->first_slice_in_pic_flag) {
 int slice_address_length;
 

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog


[FFmpeg-cvslog] avformat/dashenc: Only use temporary files when outputting to file protocol

2017-02-14 Thread Thomas Stephens
ffmpeg | branch: master | Thomas Stephens  | Tue Feb  7 
14:20:32 2017 -0600| [5fe2b437023f46394dfd4a4c991aa4a3ac3d8e72] | committer: 
Michael Niedermayer

avformat/dashenc: Only use temporary files when outputting to file protocol

Skips using temporary files when outputting to a protocol other than
"file", which enables dash to output content over network
protocols. The logic has been copied from the HLS format.

Reviewed-by: Steven Liu 
Signed-off-by: Michael Niedermayer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5fe2b437023f46394dfd4a4c991aa4a3ac3d8e72
---

 libavformat/dashenc.c | 29 +++--
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 534fa75..fa56505 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -444,9 +444,15 @@ static int write_manifest(AVFormatContext *s, int final)
 AVIOContext *out;
 char temp_filename[1024];
 int ret, i;
+const char *proto = avio_find_protocol_name(s->filename);
+int use_rename = proto && !strcmp(proto, "file");
+static unsigned int warned_non_file = 0;
 AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
 
-snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename);
+if (!use_rename && !warned_non_file++)
+av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this 
may lead to races and temporary partial files\n");
+
+snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : 
"%s", s->filename);
 ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
 if (ret < 0) {
 av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", 
temp_filename);
@@ -548,7 +554,11 @@ static int write_manifest(AVFormatContext *s, int final)
 avio_printf(out, "\n");
 avio_flush(out);
 ff_format_io_close(s, &out);
-return avpriv_io_move(temp_filename, s->filename);
+
+if (use_rename)
+return avpriv_io_move(temp_filename, s->filename);
+
+return 0;
 }
 
 static int dash_init(AVFormatContext *s)
@@ -796,6 +806,10 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 {
 DASHContext *c = s->priv_data;
 int i, ret = 0;
+
+const char *proto = avio_find_protocol_name(s->filename);
+int use_rename = proto && !strcmp(proto, "file");
+
 int cur_flush_segment_index = 0;
 if (stream >= 0)
 cur_flush_segment_index = c->streams[stream].segment_index;
@@ -833,7 +847,7 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 if (!c->single_file) {
 dash_fill_tmpl_params(filename, sizeof(filename), 
c->media_seg_name, i, os->segment_index, os->bit_rate, os->start_pts);
 snprintf(full_path, sizeof(full_path), "%s%s", c->dirname, 
filename);
-snprintf(temp_path, sizeof(temp_path), "%s.tmp", full_path);
+snprintf(temp_path, sizeof(temp_path), use_rename ? "%s.tmp" : 
"%s", full_path);
 ret = s->io_open(s, &os->out, temp_path, AVIO_FLAG_WRITE, NULL);
 if (ret < 0)
 break;
@@ -851,9 +865,12 @@ static int dash_flush(AVFormatContext *s, int final, int 
stream)
 find_index_range(s, full_path, start_pos, &index_length);
 } else {
 ff_format_io_close(s, &os->out);
-ret = avpriv_io_move(temp_path, full_path);
-if (ret < 0)
-break;
+
+if (use_rename) {
+ret = avpriv_io_move(temp_path, full_path);
+if (ret < 0)
+break;
+}
 }
 add_segment(os, filename, os->start_pts, os->max_pts - os->start_pts, 
start_pos, range_length, index_length);
 av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written 
to: %s\n", i, os->segment_index, full_path);

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog


[FFmpeg-cvslog] avcodec/h264_sei: Check actual presence of SEI picture timing instead of implying it

2017-02-14 Thread Michael Niedermayer
ffmpeg | branch: master | Michael Niedermayer  | Tue 
Feb 14 23:45:01 2017 +0100| [6a37abc59af4d87d4c55f7d812ac62d4d6a7464b] | 
committer: Michael Niedermayer

avcodec/h264_sei: Check actual presence of SEI picture timing instead of 
implying it

Signed-off-by: Michael Niedermayer 

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6a37abc59af4d87d4c55f7d812ac62d4d6a7464b
---

 libavcodec/h264_parser.c | 4 ++--
 libavcodec/h264_sei.c| 3 +++
 libavcodec/h264_sei.h| 1 +
 libavcodec/h264_slice.c  | 4 ++--
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index bca0071..bc35a61 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -471,7 +471,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
 }
 }
 
-if (sps->pic_struct_present_flag) {
+if (sps->pic_struct_present_flag && p->sei.picture_timing.present) 
{
 switch (p->sei.picture_timing.pic_struct) {
 case SEI_PIC_STRUCT_TOP_FIELD:
 case SEI_PIC_STRUCT_BOTTOM_FIELD:
@@ -502,7 +502,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
 
 if (p->picture_structure == PICT_FRAME) {
 s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
-if (sps->pic_struct_present_flag) {
+if (sps->pic_struct_present_flag && 
p->sei.picture_timing.present) {
 switch (p->sei.picture_timing.pic_struct) {
 case SEI_PIC_STRUCT_TOP_BOTTOM:
 case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 5053962..a7e627e 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -45,6 +45,7 @@ void ff_h264_sei_uninit(H264SEIContext *h)
 h->picture_timing.dpb_output_delay  = 0;
 h->picture_timing.cpb_removal_delay = -1;
 
+h->picture_timing.present  = 0;
 h->buffering_period.present= 0;
 h->frame_packing.present   = 0;
 h->display_orientation.present = 0;
@@ -119,6 +120,8 @@ static int decode_picture_timing(H264SEIPictureTiming *h, 
GetBitContext *gb,
 av_log(logctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n",
h->ct_type, h->pic_struct);
 }
+
+h->present = 1;
 return 0;
 }
 
diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h
index 9197795..da3b391 100644
--- a/libavcodec/h264_sei.h
+++ b/libavcodec/h264_sei.h
@@ -64,6 +64,7 @@ typedef enum {
 } SEI_FpaType;
 
 typedef struct H264SEIPictureTiming {
+int present;
 SEI_PicStructType pic_struct;
 
 /**
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 91a3b25..a703853 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1131,7 +1131,7 @@ static int h264_export_frame_props(H264Context *h)
 /* Prioritize picture timing SEI information over used
  * decoding process if it exists. */
 
-if (sps->pic_struct_present_flag) {
+if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
 H264SEIPictureTiming *pt = &h->sei.picture_timing;
 switch (pt->pic_struct) {
 case SEI_PIC_STRUCT_FRAME:
@@ -1176,7 +1176,7 @@ static int h264_export_frame_props(H264Context *h)
 /* Derive top_field_first from field pocs. */
 cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];
 } else {
-if (sps->pic_struct_present_flag) {
+if (sps->pic_struct_present_flag && h->sei.picture_timing.present) {
 /* Use picture timing SEI information. Even if it is a
  * information of a past frame, better than nothing. */
 if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM 
||

___
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog