mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-24 00:02:52 +00:00
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>
This commit is contained in:
parent
4b46ce8e91
commit
ecd39520b8
@ -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;
|
||||
|
@ -740,6 +740,8 @@ typedef struct H264Context {
|
||||
|
||||
int has_recovery_point;
|
||||
|
||||
int missing_fields;
|
||||
|
||||
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
|
||||
|
||||
|
@ -1663,9 +1663,11 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
|
||||
if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {
|
||||
/* Previous field is unmatched. Don't display it, but let it
|
||||
* remain for reference if marked as such. */
|
||||
h0->missing_fields ++;
|
||||
h0->cur_pic_ptr = NULL;
|
||||
h0->first_field = FIELD_PICTURE(h);
|
||||
} else {
|
||||
h0->missing_fields = 0;
|
||||
if (h0->cur_pic_ptr->frame_num != h->frame_num) {
|
||||
ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
|
||||
h0->picture_structure==PICT_BOTTOM_FIELD);
|
||||
|
Loading…
Reference in New Issue
Block a user