Merge commit 'e588615d938f8581f0d6f3771662d08cadfc00de'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 9 Jan 2014 14:10:31 +0000 (15:10 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 9 Jan 2014 14:30:50 +0000 (15:30 +0100)
* commit 'e588615d938f8581f0d6f3771662d08cadfc00de':
  hevc: fix decoding of one PU wide files

Conflicts:
libavcodec/hevc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/hevc.c
libavcodec/hevc.h

@@@ -1872,168 -2324,6 +1884,167 @@@ static int hls_decode_entry(AVCodecCont
      return ctb_addr_ts;
  }
  
-             s->HEVClcList[i]->edge_emu_buffer = av_malloc((MAX_PB_SIZE + 7) * s->frame->linesize[0]);
 +static int hls_slice_data(HEVCContext *s)
 +{
 +    int arg[2];
 +    int ret[2];
 +
 +    arg[0] = 0;
 +    arg[1] = 1;
 +
 +    s->avctx->execute(s->avctx, hls_decode_entry, arg, ret , 1, sizeof(int));
 +    return ret[0];
 +}
 +static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int job, int self_id)
 +{
 +    HEVCContext *s1  = avctxt->priv_data, *s;
 +    HEVCLocalContext *lc;
 +    int ctb_size    = 1<< s1->sps->log2_ctb_size;
 +    int more_data   = 1;
 +    int *ctb_row_p    = input_ctb_row;
 +    int ctb_row = ctb_row_p[job];
 +    int ctb_addr_rs = s1->sh.slice_ctb_addr_rs + ctb_row * ((s1->sps->width + ctb_size - 1) >> s1->sps->log2_ctb_size);
 +    int ctb_addr_ts = s1->pps->ctb_addr_rs_to_ts[ctb_addr_rs];
 +    int thread = ctb_row % s1->threads_number;
 +    int ret;
 +
 +    s = s1->sList[self_id];
 +    lc = s->HEVClc;
 +
 +    if(ctb_row) {
 +        ret = init_get_bits8(&lc->gb, s->data + s->sh.offset[ctb_row - 1], s->sh.size[ctb_row - 1]);
 +
 +        if (ret < 0)
 +            return ret;
 +        ff_init_cabac_decoder(&lc->cc, s->data + s->sh.offset[(ctb_row)-1], s->sh.size[ctb_row - 1]);
 +    }
 +
 +    while(more_data && ctb_addr_ts < s->sps->ctb_size) {
 +        int x_ctb = (ctb_addr_rs % s->sps->ctb_width) << s->sps->log2_ctb_size;
 +        int y_ctb = (ctb_addr_rs / s->sps->ctb_width) << s->sps->log2_ctb_size;
 +
 +        hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);
 +
 +        ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP);
 +
 +        if (avpriv_atomic_int_get(&s1->wpp_err)){
 +            ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
 +            return 0;
 +        }
 +
 +        ff_hevc_cabac_init(s, ctb_addr_ts);
 +        hls_sao_param(s, x_ctb >> s->sps->log2_ctb_size, y_ctb >> s->sps->log2_ctb_size);
 +        more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0);
 +
 +        if (more_data < 0)
 +            return more_data;
 +
 +        ctb_addr_ts++;
 +
 +        ff_hevc_save_states(s, ctb_addr_ts);
 +        ff_thread_report_progress2(s->avctx, ctb_row, thread, 1);
 +        ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);
 +
 +        if (!more_data && (x_ctb+ctb_size) < s->sps->width && ctb_row != s->sh.num_entry_point_offsets) {
 +            avpriv_atomic_int_set(&s1->wpp_err,  1);
 +            ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP);
 +            return 0;
 +        }
 +
 +        if ((x_ctb+ctb_size) >= s->sps->width && (y_ctb+ctb_size) >= s->sps->height ) {
 +            ff_hevc_hls_filter(s, x_ctb, y_ctb);
 +            ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP);
 +            return ctb_addr_ts;
 +        }
 +        ctb_addr_rs       = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
 +        x_ctb+=ctb_size;
 +
 +        if(x_ctb >= s->sps->width) {
 +            break;
 +        }
 +    }
 +    ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP);
 +
 +    return 0;
 +}
 +
 +static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length)
 +{
 +    HEVCLocalContext *lc = s->HEVClc;
 +    int *ret = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int));
 +    int *arg = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int));
 +    int offset;
 +    int startheader, cmpt = 0;
 +    int i, j, res = 0;
 +
 +
 +    if (!s->sList[1]) {
 +        ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
 +
 +
 +        for (i = 1; i < s->threads_number; i++) {
 +            s->sList[i] = av_malloc(sizeof(HEVCContext));
 +            memcpy(s->sList[i], s, sizeof(HEVCContext));
 +            s->HEVClcList[i] = av_malloc(sizeof(HEVCLocalContext));
 +            s->sList[i]->HEVClc = s->HEVClcList[i];
 +        }
 +    }
 +
 +    offset = (lc->gb.index >> 3);
 +
 +    for (j = 0, cmpt = 0, startheader = offset + s->sh.entry_point_offset[0]; j < s->skipped_bytes; j++) {
 +        if (s->skipped_bytes_pos[j] >= offset && s->skipped_bytes_pos[j] < startheader) {
 +            startheader--;
 +            cmpt++;
 +        }
 +    }
 +
 +    for (i = 1; i < s->sh.num_entry_point_offsets; i++) {
 +        offset += (s->sh.entry_point_offset[i - 1] - cmpt);
 +        for (j = 0, cmpt = 0, startheader = offset
 +             + s->sh.entry_point_offset[i]; j < s->skipped_bytes; j++) {
 +            if (s->skipped_bytes_pos[j] >= offset && s->skipped_bytes_pos[j] < startheader) {
 +                startheader--;
 +                cmpt++;
 +            }
 +        }
 +        s->sh.size[i - 1] = s->sh.entry_point_offset[i] - cmpt;
 +        s->sh.offset[i - 1] = offset;
 +
 +    }
 +    if (s->sh.num_entry_point_offsets != 0) {
 +        offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt;
 +        s->sh.size[s->sh.num_entry_point_offsets - 1] = length - offset;
 +        s->sh.offset[s->sh.num_entry_point_offsets - 1] = offset;
 +
 +    }
 +    s->data = nal;
 +
 +    for (i = 1; i < s->threads_number; i++) {
 +        s->sList[i]->HEVClc->first_qp_group = 1;
 +        s->sList[i]->HEVClc->qp_y = s->sList[0]->HEVClc->qp_y;
 +        memcpy(s->sList[i], s, sizeof(HEVCContext));
 +        s->sList[i]->HEVClc = s->HEVClcList[i];
 +    }
 +
 +    avpriv_atomic_int_set(&s->wpp_err, 0);
 +    ff_reset_entries(s->avctx);
 +
 +    for (i = 0; i <= s->sh.num_entry_point_offsets; i++) {
 +        arg[i] = i;
 +        ret[i] = 0;
 +    }
 +
 +    if (s->pps->entropy_coding_sync_enabled_flag)
 +        s->avctx->execute2(s->avctx, (void *) hls_decode_entry_wpp, arg, ret, s->sh.num_entry_point_offsets + 1);
 +
 +    for (i = 0; i <= s->sh.num_entry_point_offsets; i++)
 +        res += ret[i];
 +    av_free(ret);
 +    av_free(arg);
 +    return res;
 +}
 +
  /**
   * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit,
   * 0 if the unit should be skipped, 1 otherwise
@@@ -2688,19 -2933,8 +2692,17 @@@ static av_cold int hevc_decode_free(AVC
  
      pic_arrays_free(s);
  
-     if (lc)
-         av_freep(&lc->edge_emu_buffer);
      av_freep(&s->md5_ctx);
  
 +    for(i=0; i < s->nals_allocated; i++) {
 +        av_freep(&s->skipped_bytes_pos_nal[i]);
 +    }
 +    av_freep(&s->skipped_bytes_pos_size_nal);
 +    av_freep(&s->skipped_bytes_nal);
 +    av_freep(&s->skipped_bytes_pos_nal);
 +
 +    av_freep(&s->cabac_state);
 +
      av_frame_free(&s->tmp_frame);
      av_frame_free(&s->output_frame);
  
      for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
          av_buffer_unref(&s->pps_list[i]);
  
-             av_freep(&lc->edge_emu_buffer);
 +    av_freep(&s->sh.entry_point_offset);
 +    av_freep(&s->sh.offset);
 +    av_freep(&s->sh.size);
 +
 +    for (i = 1; i < s->threads_number; i++) {
 +        lc = s->HEVClcList[i];
 +        if (lc) {
 +            av_freep(&s->HEVClcList[i]);
 +            av_freep(&s->sList[i]);
 +        }
 +    }
 +    if (s->HEVClc == s->HEVClcList[0])
 +        s->HEVClc = NULL;
 +    av_freep(&s->HEVClcList[0]);
 +
      for (i = 0; i < s->nals_allocated; i++)
          av_freep(&s->nals[i].rbsp_buffer);
      av_freep(&s->nals);
Simple merge