]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/hevc_parser.c
Merge commit '708e84cda1bdbffb92847f3d6ccf6fbeb26d9948'
[ffmpeg] / libavcodec / hevc_parser.c
index 4f41b78f6653a8106021a8f319d250feb48b487a..dc63c6b95433bf3e13dbd84fa35ef914dc04f980 100644 (file)
@@ -49,49 +49,6 @@ typedef struct HEVCParserContext {
     int pocTid0;
 } HEVCParserContext;
 
-/**
- * Find the end of the current frame in the bitstream.
- * @return the position of the first byte of the next frame, or END_NOT_FOUND
- */
-static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
-                               int buf_size)
-{
-    int i;
-    ParseContext *pc = s->priv_data;
-
-    for (i = 0; i < buf_size; i++) {
-        int nut;
-
-        pc->state64 = (pc->state64 << 8) | buf[i];
-
-        if (((pc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE)
-            continue;
-
-        nut = (pc->state64 >> 2 * 8 + 1) & 0x3F;
-        // Beginning of access unit
-        if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_AUD) || nut == HEVC_NAL_SEI_PREFIX ||
-            (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
-            if (pc->frame_start_found) {
-                pc->frame_start_found = 0;
-                return i - 5;
-            }
-        } else if (nut <= HEVC_NAL_RASL_R ||
-                   (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) {
-            int first_slice_segment_in_pic_flag = buf[i] >> 7;
-            if (first_slice_segment_in_pic_flag) {
-                if (!pc->frame_start_found) {
-                    pc->frame_start_found = 1;
-                } else { // First slice of next frame found
-                    pc->frame_start_found = 0;
-                    return i - 5;
-                }
-            }
-        }
-    }
-
-    return END_NOT_FOUND;
-}
-
 static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
                                    AVCodecContext *avctx)
 {
@@ -100,6 +57,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
     HEVCSEIContext *sei = &ctx->sei;
     SliceHeader *sh = &ctx->sh;
     GetBitContext *gb = &nal->gb;
+    const HEVCWindow *ow;
     int i, num = 0, den = 0;
 
     sh->first_slice_in_pic_flag = get_bits1(gb);
@@ -126,11 +84,12 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
         ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data;
         ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data;
     }
+    ow  = &ps->sps->output_window;
 
     s->coded_width  = ps->sps->width;
     s->coded_height = ps->sps->height;
-    s->width        = ps->sps->output_width;
-    s->height       = ps->sps->output_height;
+    s->width        = ps->sps->width  - ow->left_offset - ow->right_offset;
+    s->height       = ps->sps->height - ow->top_offset  - ow->bottom_offset;
     s->format       = ps->sps->pix_fmt;
     avctx->profile  = ps->sps->ptl.general_ptl.profile_idc;
     avctx->level    = ps->sps->ptl.general_ptl.level_idc;
@@ -216,14 +175,14 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
  * @param buf buffer with field/frame data.
  * @param buf_size size of the buffer.
  */
-static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
+static int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
                            int buf_size, AVCodecContext *avctx)
 {
     HEVCParserContext *ctx = s->priv_data;
     HEVCParamSets *ps = &ctx->ps;
     HEVCSEIContext *sei = &ctx->sei;
     int is_global = buf == avctx->extradata;
-    int i, ret;
+    int ret, i;
 
     /* set some sane default values */
     s->pict_type         = AV_PICTURE_TYPE_I;
@@ -261,16 +220,16 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
         case HEVC_NAL_TSA_R:
         case HEVC_NAL_STSA_N:
         case HEVC_NAL_STSA_R:
-        case HEVC_NAL_RADL_N:
-        case HEVC_NAL_RADL_R:
-        case HEVC_NAL_RASL_N:
-        case HEVC_NAL_RASL_R:
         case HEVC_NAL_BLA_W_LP:
         case HEVC_NAL_BLA_W_RADL:
         case HEVC_NAL_BLA_N_LP:
         case HEVC_NAL_IDR_W_RADL:
         case HEVC_NAL_IDR_N_LP:
         case HEVC_NAL_CRA_NUT:
+        case HEVC_NAL_RADL_N:
+        case HEVC_NAL_RADL_R:
+        case HEVC_NAL_RASL_N:
+        case HEVC_NAL_RASL_R:
 
             if (is_global) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid NAL unit: %d\n", nal->type);
@@ -289,8 +248,51 @@ static inline int parse_nal_units(AVCodecParserContext *s, const uint8_t *buf,
     return -1;
 }
 
-static int hevc_parse(AVCodecParserContext *s,
-                      AVCodecContext *avctx,
+/**
+ * Find the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or END_NOT_FOUND
+ */
+static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
+                               int buf_size)
+{
+    HEVCParserContext *ctx = s->priv_data;
+    ParseContext       *pc = &ctx->pc;
+    int i;
+
+    for (i = 0; i < buf_size; i++) {
+        int nut;
+
+        pc->state64 = (pc->state64 << 8) | buf[i];
+
+        if (((pc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE)
+            continue;
+
+        nut = (pc->state64 >> 2 * 8 + 1) & 0x3F;
+        // Beginning of access unit
+        if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut == HEVC_NAL_SEI_PREFIX ||
+            (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
+            if (pc->frame_start_found) {
+                pc->frame_start_found = 0;
+                return i - 5;
+            }
+        } else if (nut <= HEVC_NAL_RASL_R ||
+                   (nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) {
+            int first_slice_segment_in_pic_flag = buf[i] >> 7;
+            if (first_slice_segment_in_pic_flag) {
+                if (!pc->frame_start_found) {
+                    pc->frame_start_found = 1;
+                } else { // First slice of next frame found
+                    pc->frame_start_found = 0;
+                    return i - 5;
+                }
+            }
+        }
+    }
+
+    return END_NOT_FOUND;
+}
+
+static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                       const uint8_t **poutbuf, int *poutbuf_size,
                       const uint8_t *buf, int buf_size)
 {
@@ -369,6 +371,7 @@ static void hevc_parser_close(AVCodecParserContext *s)
     ctx->ps.sps = NULL;
 
     ff_h2645_packet_uninit(&ctx->pkt);
+    ff_hevc_reset_sei(&ctx->sei);
 
     av_freep(&ctx->pc.buffer);
 }