]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpegvideo.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / mpegvideo.c
index 5c04e9d0789f4917e547e3f26c0834fdfb69f6d8..f197bd78a26cbd959024166fa4b4c4c054c61bc7 100644 (file)
@@ -531,7 +531,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 {
     MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
 
-    if (dst == src || !s1->context_initialized)
+    if (dst == src)
         return 0;
 
     // FIXME can parameters change on I-frames?
@@ -540,12 +540,14 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         memcpy(s, s1, sizeof(MpegEncContext));
 
         s->avctx                 = dst;
-        s->picture_range_start  += MAX_PICTURE_COUNT;
-        s->picture_range_end    += MAX_PICTURE_COUNT;
         s->bitstream_buffer      = NULL;
         s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0;
 
-        MPV_common_init(s);
+        if (s1->context_initialized){
+            s->picture_range_start  += MAX_PICTURE_COUNT;
+            s->picture_range_end    += MAX_PICTURE_COUNT;
+            MPV_common_init(s);
+        }
     }
 
     s->avctx->coded_height  = s1->avctx->coded_height;
@@ -638,6 +640,8 @@ void MPV_common_defaults(MpegEncContext *s)
 
     s->picture_range_start   = 0;
     s->picture_range_end     = MAX_PICTURE_COUNT;
+
+    s->slice_context_count   = 1;
 }
 
 /**
@@ -656,11 +660,13 @@ void MPV_decode_defaults(MpegEncContext *s)
  */
 av_cold int MPV_common_init(MpegEncContext *s)
 {
-    int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y,
-        threads = (s->encoding ||
-                   (HAVE_THREADS &&
-                    s->avctx->active_thread_type & FF_THREAD_SLICE)) ?
-                  s->avctx->thread_count : 1;
+    int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
+    int nb_slices = (HAVE_THREADS &&
+                     s->avctx->active_thread_type & FF_THREAD_SLICE) ?
+                    s->avctx->thread_count : 1;
+
+    if (s->encoding && s->avctx->slices)
+        nb_slices = s->avctx->slices;
 
     if (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
         s->mb_height = (s->height + 31) / 32 * 2;
@@ -673,14 +679,15 @@ av_cold int MPV_common_init(MpegEncContext *s)
         return -1;
     }
 
-    if ((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) &&
-        (s->avctx->thread_count > MAX_THREADS ||
-         (s->avctx->thread_count > s->mb_height && s->mb_height))) {
-        int max_threads = FFMIN(MAX_THREADS, s->mb_height);
-        av_log(s->avctx, AV_LOG_WARNING,
-               "too many threads (%d), reducing to %d\n",
-               s->avctx->thread_count, max_threads);
-        threads = max_threads;
+    if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) {
+        int max_slices;
+        if (s->mb_height)
+            max_slices = FFMIN(MAX_THREADS, s->mb_height);
+        else
+            max_slices = MAX_THREADS;
+        av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"
+               " reducing to %d\n", nb_slices, max_slices);
+        nb_slices = max_slices;
     }
 
     if ((s->width || s->height) &&
@@ -699,9 +706,9 @@ av_cold int MPV_common_init(MpegEncContext *s)
     mb_array_size = s->mb_height * s->mb_stride;
     mv_table_size = (s->mb_height + 2) * s->mb_stride + 1;
 
-    /* set chroma shifts */
-    avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,&(s->chroma_x_shift),
-                                                    &(s->chroma_y_shift) );
+        /* set chroma shifts */
+        avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &s->chroma_x_shift,
+                                      &s->chroma_y_shift);
 
     /* set default edge pos, will be overriden in decode_header if needed */
     s->h_edge_pos = s->mb_width * 16;
@@ -831,17 +838,20 @@ av_cold int MPV_common_init(MpegEncContext *s)
         s->context_initialized = 1;
         s->thread_context[0]   = s;
 
-        if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) {
-            for (i = 1; i < threads; i++) {
+//     if (s->width && s->height) {
+        if (nb_slices > 1) {
+            for (i = 1; i < nb_slices; i++) {
                 s->thread_context[i] = av_malloc(sizeof(MpegEncContext));
                 memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
             }
 
-            for (i = 0; i < threads; i++) {
+            for (i = 0; i < nb_slices; i++) {
                 if (init_duplicate_context(s->thread_context[i], s) < 0)
                     goto fail;
-                s->thread_context[i]->start_mb_y = (s->mb_height*(i  ) + s->avctx->thread_count / 2) / s->avctx->thread_count;
-                s->thread_context[i]->end_mb_y   = (s->mb_height*(i+1) + s->avctx->thread_count / 2) / s->avctx->thread_count;
+                    s->thread_context[i]->start_mb_y =
+                        (s->mb_height * (i) + nb_slices / 2) / nb_slices;
+                    s->thread_context[i]->end_mb_y   =
+                        (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
             }
         } else {
             if (init_duplicate_context(s, s) < 0)
@@ -849,6 +859,8 @@ av_cold int MPV_common_init(MpegEncContext *s)
             s->start_mb_y = 0;
             s->end_mb_y   = s->mb_height;
         }
+        s->slice_context_count = nb_slices;
+//     }
 
     return 0;
  fail:
@@ -861,13 +873,14 @@ void MPV_common_end(MpegEncContext *s)
 {
     int i, j, k;
 
-    if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_SLICE)) {
-        for (i = 0; i < s->avctx->thread_count; i++) {
+    if (s->slice_context_count > 1) {
+        for (i = 0; i < s->slice_context_count; i++) {
             free_duplicate_context(s->thread_context[i]);
         }
-        for (i = 1; i < s->avctx->thread_count; i++) {
+        for (i = 1; i < s->slice_context_count; i++) {
             av_freep(&s->thread_context[i]);
         }
+        s->slice_context_count = 1;
     } else free_duplicate_context(s);
 
     av_freep(&s->parse_context.buffer);
@@ -1124,25 +1137,26 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
            s->codec_id == CODEC_ID_SVQ3);
 
     /* mark & release old frames */
-    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
-        s->last_picture_ptr != s->next_picture_ptr &&
-        s->last_picture_ptr->f.data[0]) {
-        if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) {
+    if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) {
+        if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
+            s->last_picture_ptr != s->next_picture_ptr &&
+            s->last_picture_ptr->f.data[0]) {
             if (s->last_picture_ptr->owner2 == s)
                 free_frame_buffer(s, s->last_picture_ptr);
+        }
 
-            /* release forgotten pictures */
-            /* if (mpeg124/h263) */
-            if (!s->encoding) {
-                for (i = 0; i < s->picture_count; i++) {
-                    if (s->picture[i].owner2 == s && s->picture[i].f.data[0] &&
-                        &s->picture[i] != s->next_picture_ptr &&
-                        s->picture[i].f.reference) {
-                        if (!(avctx->active_thread_type & FF_THREAD_FRAME))
-                            av_log(avctx, AV_LOG_ERROR,
-                                   "releasing zombie picture\n");
-                        free_frame_buffer(s, &s->picture[i]);
-                    }
+        /* release forgotten pictures */
+        /* if (mpeg124/h263) */
+        if (!s->encoding) {
+            for (i = 0; i < s->picture_count; i++) {
+                if (s->picture[i].owner2 == s && s->picture[i].f.data[0] &&
+                    &s->picture[i] != s->last_picture_ptr &&
+                    &s->picture[i] != s->next_picture_ptr &&
+                    s->picture[i].f.reference) {
+                    if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+                        av_log(avctx, AV_LOG_ERROR,
+                               "releasing zombie picture\n");
+                    free_frame_buffer(s, &s->picture[i]);
                 }
             }
         }
@@ -1263,6 +1277,14 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     if (s->next_picture_ptr)
         ff_copy_picture(&s->next_picture, s->next_picture_ptr);
 
+    if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME) &&
+        (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3)) {
+        if (s->next_picture_ptr)
+            s->next_picture_ptr->owner2 = s;
+        if (s->last_picture_ptr)
+            s->last_picture_ptr->owner2 = s;
+    }
+
     assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
                                                  s->last_picture_ptr->f.data[0]));
 
@@ -1324,15 +1346,15 @@ void MPV_frame_end(MpegEncContext *s)
               !(s->flags & CODEC_FLAG_EMU_EDGE)) {
         int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w;
         int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h;
-        s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize,
+        s->dsp.draw_edges(s->current_picture.f.data[0], s->current_picture.f.linesize[0],
                           s->h_edge_pos, s->v_edge_pos,
                           EDGE_WIDTH, EDGE_WIDTH,
                           EDGE_TOP | EDGE_BOTTOM);
-        s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize,
+        s->dsp.draw_edges(s->current_picture.f.data[1], s->current_picture.f.linesize[1],
                           s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
                           EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
                           EDGE_TOP | EDGE_BOTTOM);
-        s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize,
+        s->dsp.draw_edges(s->current_picture.f.data[2], s->current_picture.f.linesize[2],
                           s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
                           EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
                           EDGE_TOP | EDGE_BOTTOM);
@@ -1785,8 +1807,8 @@ static inline int hpel_motion_lowres(MpegEncContext *s,
 
     src   += src_y * stride + src_x;
 
-    if ((unsigned)src_x >  h_edge_pos - (!!sx) - w ||
-        (unsigned)src_y > (v_edge_pos >> field_based) - (!!sy) - h) {
+    if ((unsigned)src_x > FFMAX( h_edge_pos - (!!sx) - w,                 0) ||
+        (unsigned)src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
         s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w + 1,
                                 (h + 1) << field_based, src_x,
                                 src_y   << field_based,
@@ -1887,8 +1909,8 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s,
     ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
     ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
 
-    if ((unsigned) src_x >  h_edge_pos - (!!sx) - 2 * block_s ||
-        (unsigned) src_y > (v_edge_pos >> field_based) - (!!sy) - h) {
+    if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s,       0) ||
+        (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
         s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
                                 s->linesize, 17, 17 + field_based,
                                 src_x, src_y << field_based, h_edge_pos,
@@ -1970,8 +1992,8 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
     offset = src_y * s->uvlinesize + src_x;
     ptr = ref_picture[1] + offset;
     if (s->flags & CODEC_FLAG_EMU_EDGE) {
-        if ((unsigned) src_x > h_edge_pos - (!!sx) - block_s ||
-            (unsigned) src_y > v_edge_pos - (!!sy) - block_s) {
+        if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) ||
+            (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) {
             s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
                                     9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
             ptr = s->edge_emu_buffer;
@@ -2307,7 +2329,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
         }
 
         dct_linesize = linesize << s->interlaced_dct;
-        dct_offset =(s->interlaced_dct)? linesize : linesize*block_size;
+        dct_offset   = s->interlaced_dct ? linesize : linesize * block_size;
 
         if(readable){
             dest_y=  s->dest[0];
@@ -2403,7 +2425,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
                     }else{
                         //chroma422
                         dct_linesize = uvlinesize << s->interlaced_dct;
-                        dct_offset =(s->interlaced_dct)? uvlinesize : uvlinesize*block_size;
+                        dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
 
                         add_dct(s, block[4], 4, dest_cb, dct_linesize);
                         add_dct(s, block[5], 5, dest_cr, dct_linesize);
@@ -2455,7 +2477,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
                     }else{
 
                         dct_linesize = uvlinesize << s->interlaced_dct;
-                        dct_offset =(s->interlaced_dct)? uvlinesize : uvlinesize*block_size;
+                        dct_offset   = s->interlaced_dct? uvlinesize : uvlinesize*block_size;
 
                         s->dsp.idct_put(dest_cb,              dct_linesize, block[4]);
                         s->dsp.idct_put(dest_cr,              dct_linesize, block[5]);