changeset 8972:eaf39f9b25df libavcodec

Parse buffering period (H.264, D.1.1). Patch by Ivan Schreter, schreter gmx net
author cehoyos
date Wed, 18 Feb 2009 23:33:30 +0000
parents 734114ba02fa
children 34f2c7189710
files h264.c h264.h
diffstat 2 files changed, 43 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/h264.c	Wed Feb 18 23:32:41 2009 +0000
+++ b/h264.c	Wed Feb 18 23:33:30 2009 +0000
@@ -2211,6 +2211,7 @@
     h->sei_recovery_frame_cnt = -1;
     h->sei_dpb_output_delay = 0;
     h->sei_cpb_removal_delay = -1;
+    h->sei_buffering_period_present = 0;
     return 0;
 }
 
@@ -3148,6 +3149,7 @@
     h->sei_recovery_frame_cnt = -1;
     h->sei_dpb_output_delay = 0;
     h->sei_cpb_removal_delay = -1;
+    h->sei_buffering_period_present = 0;
     ff_mpeg_flush(avctx);
 }
 
@@ -6864,6 +6866,37 @@
     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){
     MpegEncContext * const s = &h->s;
 
@@ -6893,6 +6926,10 @@
             if(decode_recovery_point(h) < 0)
                 return -1;
             break;
+        case SEI_BUFFERING_PERIOD:
+            if(decode_buffering_period(h) < 0)
+                return -1;
+            break;
         default:
             skip_bits(&s->gb, 8*size);
         }
@@ -7698,6 +7735,7 @@
         h->sei_recovery_frame_cnt = -1;
         h->sei_dpb_output_delay = 0;
         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) {
             /* Wait for second field. */
--- a/h264.h	Wed Feb 18 23:32:41 2009 +0000
+++ b/h264.h	Wed Feb 18 23:33:30 2009 +0000
@@ -115,6 +115,7 @@
  * SEI message types
  */
 typedef enum {
+    SEI_BUFFERING_PERIOD             =  0, ///< buffering period (H.264, D.1.1)
     SEI_TYPE_PIC_TIMING              =  1, ///< picture timing
     SEI_TYPE_USER_DATA_UNREGISTERED  =  5, ///< unregistered user data
     SEI_TYPE_RECOVERY_POINT          =  6  ///< recovery point (frame # to decoder sync)
@@ -525,6 +526,10 @@
 
     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
+
+    // Timestamp stuff
+    int sei_buffering_period_present;  ///< Buffering period SEI flag
+    int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
 }H264Context;
 
 #endif /* AVCODEC_H264_H */