Commit a89dbf1e authored by cehoyos's avatar cehoyos

Parse buffering period (H.264, D.1.1).

Patch by Ivan Schreter, schreter gmx net


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@17441 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 0e704ee7
...@@ -2211,6 +2211,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ ...@@ -2211,6 +2211,7 @@ static av_cold int decode_init(AVCodecContext *avctx){
h->sei_recovery_frame_cnt = -1; h->sei_recovery_frame_cnt = -1;
h->sei_dpb_output_delay = 0; h->sei_dpb_output_delay = 0;
h->sei_cpb_removal_delay = -1; h->sei_cpb_removal_delay = -1;
h->sei_buffering_period_present = 0;
return 0; return 0;
} }
...@@ -3148,6 +3149,7 @@ static void flush_dpb(AVCodecContext *avctx){ ...@@ -3148,6 +3149,7 @@ static void flush_dpb(AVCodecContext *avctx){
h->sei_recovery_frame_cnt = -1; h->sei_recovery_frame_cnt = -1;
h->sei_dpb_output_delay = 0; h->sei_dpb_output_delay = 0;
h->sei_cpb_removal_delay = -1; h->sei_cpb_removal_delay = -1;
h->sei_buffering_period_present = 0;
ff_mpeg_flush(avctx); ff_mpeg_flush(avctx);
} }
...@@ -6864,6 +6866,37 @@ static int decode_recovery_point(H264Context *h){ ...@@ -6864,6 +6866,37 @@ static int decode_recovery_point(H264Context *h){
return 0; return 0;
} }
static int decode_buffering_period(H264Context *h){
MpegEncContext * const s = &h->s;
unsigned int sps_id;
int sched_sel_idx;
SPS *sps;
sps_id = get_ue_golomb_31(&s->gb);
if(sps_id > 31 || !h->sps_buffers[sps_id]) {
av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id);
return -1;
}
sps = h->sps_buffers[sps_id];
// NOTE: This is really so duplicated in the standard... See H.264, D.1.1
if (sps->nal_hrd_parameters_present_flag) {
for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length);
skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
}
}
if (sps->vcl_hrd_parameters_present_flag) {
for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length);
skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
}
}
h->sei_buffering_period_present = 1;
return 0;
}
static int decode_sei(H264Context *h){ static int decode_sei(H264Context *h){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
...@@ -6893,6 +6926,10 @@ static int decode_sei(H264Context *h){ ...@@ -6893,6 +6926,10 @@ static int decode_sei(H264Context *h){
if(decode_recovery_point(h) < 0) if(decode_recovery_point(h) < 0)
return -1; return -1;
break; break;
case SEI_BUFFERING_PERIOD:
if(decode_buffering_period(h) < 0)
return -1;
break;
default: default:
skip_bits(&s->gb, 8*size); skip_bits(&s->gb, 8*size);
} }
...@@ -7698,6 +7735,7 @@ static int decode_frame(AVCodecContext *avctx, ...@@ -7698,6 +7735,7 @@ static int decode_frame(AVCodecContext *avctx,
h->sei_recovery_frame_cnt = -1; h->sei_recovery_frame_cnt = -1;
h->sei_dpb_output_delay = 0; h->sei_dpb_output_delay = 0;
h->sei_cpb_removal_delay = -1; h->sei_cpb_removal_delay = -1;
h->sei_buffering_period_present = 0;
if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) { if (cur->field_poc[0]==INT_MAX || cur->field_poc[1]==INT_MAX) {
/* Wait for second field. */ /* Wait for second field. */
......
...@@ -115,6 +115,7 @@ enum { ...@@ -115,6 +115,7 @@ enum {
* SEI message types * SEI message types
*/ */
typedef enum { typedef enum {
SEI_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1)
SEI_TYPE_PIC_TIMING = 1, ///< picture timing SEI_TYPE_PIC_TIMING = 1, ///< picture timing
SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data
SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync) SEI_TYPE_RECOVERY_POINT = 6 ///< recovery point (frame # to decoder sync)
...@@ -525,6 +526,10 @@ typedef struct H264Context{ ...@@ -525,6 +526,10 @@ typedef struct H264Context{
int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag
int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag
// Timestamp stuff
int sei_buffering_period_present; ///< Buffering period SEI flag
int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
}H264Context; }H264Context;
#endif /* AVCODEC_H264_H */ #endif /* AVCODEC_H264_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment