diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2015-01-20 20:30:53 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-01-23 00:47:24 +0100 |
commit | ecd39520b83ecc2f10a884b6c2a5594247806601 (patch) | |
tree | 04f6a52a9651dd31996e24256d5d2559c36d68fa /libavcodec/h264.c | |
parent | 4b46ce8e91bdcf0726f669525609f77fc1a88472 (diff) |
avcodec/h264: Partially decode and display single fields try #2
This like the previous attempt does not fully correctly decode this
type of non standard H.264, but it now works fully automatic
requiring no manual filters or flags to be used
See Ticket2254
Reviewed-by: Kieran Kunhya <kierank@obe.tv>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index ab9acde7cb..23f775414f 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -762,7 +762,10 @@ static void decode_postinit(H264Context *h, int setup_finished) * yet, so we assume the worst for now. */ // if (setup_finished) // ff_thread_finish_setup(h->avctx); - return; + if (cur->field_poc[0] == INT_MAX && cur->field_poc[1] == INT_MAX) + return; + if (h->avctx->hwaccel || h->missing_fields <=1) + return; } cur->f.interlaced_frame = 0; @@ -1912,6 +1915,29 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (!h->next_output_pic->recovered) h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT; + if (!h->avctx->hwaccel && + (h->next_output_pic->field_poc[0] == INT_MAX || + h->next_output_pic->field_poc[1] == INT_MAX) + ) { + int p; + AVFrame *f = &h->next_output_pic->f; + int field = h->next_output_pic->field_poc[0] == INT_MAX; + uint8_t *dst_data[4]; + int linesizes[4]; + const uint8_t *src_data[4]; + + av_log(h->avctx, AV_LOG_DEBUG, "Duplicating field %d to fill missing\n", field); + + for (p = 0; p<4; p++) { + dst_data[p] = f->data[p] + (field^1)*f->linesize[p]; + src_data[p] = f->data[p] + field *f->linesize[p]; + linesizes[p] = 2*f->linesize[p]; + } + + av_image_copy(dst_data, linesizes, src_data, linesizes, + f->format, f->width, f->height>>1); + } + ret = output_frame(h, pict, h->next_output_pic); if (ret < 0) return ret; |