/*
* MPEG-1/2 decoder
- * Copyright (c) 2000,2001 Fabrice Bellard.
+ * Copyright (c) 2000,2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*/
/**
- * @file mpeg12.c
+ * @file libavcodec/mpeg12.c
* MPEG-1/2 decoder
*/
//#define DEBUG
+#include "internal.h"
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "mpeg12data.h"
#include "mpeg12decdata.h"
#include "bytestream.h"
+#include "vdpau_internal.h"
+#include "xvmc_internal.h"
//#undef NDEBUG
//#include <assert.h>
#define MB_PTYPE_VLC_BITS 6
#define MB_BTYPE_VLC_BITS 6
-static inline int mpeg1_decode_block_inter(MpegEncContext *s,
+static inline int mpeg1_decode_block_intra(MpegEncContext *s,
DCTELEM *block,
int n);
-static inline int mpeg1_decode_block_intra(MpegEncContext *s,
+static inline int mpeg1_decode_block_inter(MpegEncContext *s,
DCTELEM *block,
int n);
static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n);
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
static void exchange_uv(MpegEncContext *s);
-int XVMC_field_start(MpegEncContext *s, AVCodecContext *avctx);
-int XVMC_field_end(MpegEncContext *s);
-void XVMC_pack_pblocks(MpegEncContext *s,int cbp);
-void XVMC_init_block(MpegEncContext *s);//set s->block
-
static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = {
PIX_FMT_XVMC_MPEG2_IDCT,
PIX_FMT_XVMC_MPEG2_MC,
}else
memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
s->mb_intra = 1;
-#ifdef CONFIG_XVMC
//if 1, we memcpy blocks in xvmcvideo
- if(s->avctx->xvmc_acceleration > 1){
- XVMC_pack_pblocks(s,-1);//inter are always full blocks
+ if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){
+ ff_xvmc_pack_pblocks(s,-1);//inter are always full blocks
if(s->swap_uv){
exchange_uv(s);
}
}
-#endif
if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
if(s->flags2 & CODEC_FLAG2_FAST){
for(i=0;i<6;i++) {
- mpeg2_fast_decode_block_intra(s, s->pblocks[i], i);
+ mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
}
}else{
for(i=0;i<mb_block_count;i++) {
- if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0)
+ if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
return -1;
}
}
} else {
for(i=0;i<6;i++) {
- if (mpeg1_decode_block_intra(s, s->pblocks[i], i) < 0)
+ if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
return -1;
}
}
for(i=0;i<2;i++) {
if (USES_LIST(mb_type, i)) {
int dmx, dmy, mx, my, m;
+ const int my_shift= s->picture_structure == PICT_FRAME;
+
mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
s->last_mv[i][0][0]);
s->last_mv[i][0][0] = mx;
s->last_mv[i][1][0] = mx;
dmx = get_dmv(s);
my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][0][1] >> 1);
+ s->last_mv[i][0][1] >> my_shift);
dmy = get_dmv(s);
- s->last_mv[i][0][1] = my<<1;
- s->last_mv[i][1][1] = my<<1;
+ s->last_mv[i][0][1] = my<<my_shift;
+ s->last_mv[i][1][1] = my<<my_shift;
s->mv[i][0][0] = mx;
s->mv[i][0][1] = my;
return -1;
}
-#ifdef CONFIG_XVMC
//if 1, we memcpy blocks in xvmcvideo
- if(s->avctx->xvmc_acceleration > 1){
- XVMC_pack_pblocks(s,cbp);
+ if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1){
+ ff_xvmc_pack_pblocks(s,cbp);
if(s->swap_uv){
exchange_uv(s);
}
}
-#endif
if (s->codec_id == CODEC_ID_MPEG2VIDEO) {
if(s->flags2 & CODEC_FLAG2_FAST){
for(i=0;i<6;i++) {
if(cbp & 32) {
- mpeg2_fast_decode_block_non_intra(s, s->pblocks[i], i);
+ mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
} else {
s->block_last_index[i] = -1;
}
for(i=0;i<mb_block_count;i++) {
if ( cbp & (1<<11) ) {
- if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0)
+ if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
return -1;
} else {
s->block_last_index[i] = -1;
if(s->flags2 & CODEC_FLAG2_FAST){
for(i=0;i<6;i++) {
if (cbp & 32) {
- mpeg1_fast_decode_block_inter(s, s->pblocks[i], i);
+ mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
} else {
s->block_last_index[i] = -1;
}
}else{
for(i=0;i<6;i++) {
if (cbp & 32) {
- if (mpeg1_decode_block_inter(s, s->pblocks[i], i) < 0)
+ if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
return -1;
} else {
s->block_last_index[i] = -1;
dc = s->last_dc[component];
dc += diff;
s->last_dc[component] = dc;
- block[0] = dc<<3;
+ block[0] = dc*quant_matrix[0];
dprintf(s->avctx, "dc=%d diff=%d\n", dc, diff);
i = 0;
{
return 0;
}
+int ff_mpeg1_decode_block_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n)
+{
+ return mpeg1_decode_block_intra(s, block, n);
+}
+
static inline int mpeg1_decode_block_inter(MpegEncContext *s,
DCTELEM *block,
int n)
int slice_count;
int swap_uv;//indicate VCR2
int save_aspect_info;
- int save_width, save_height;
+ int save_width, save_height, save_progressive_seq;
AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator
-
+ int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
} Mpeg1Context;
static av_cold int mpeg_decode_init(AVCodecContext *avctx)
s->mpeg_enc_ctx.picture_number = 0;
s->repeat_field = 0;
s->mpeg_enc_ctx.codec_id= avctx->codec->id;
+ avctx->color_range= AVCOL_RANGE_MPEG;
+ if (avctx->codec->id == CODEC_ID_MPEG1VIDEO)
+ avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
+ else
+ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
return 0;
}
}
}
-static enum PixelFormat mpeg_set_pixelformat(AVCodecContext *avctx){
+static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx){
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
if(avctx->xvmc_acceleration)
return avctx->get_format(avctx,pixfmt_xvmc_mpg2_420);
- else{
+ else if(avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU){
+ if(avctx->codec_id == CODEC_ID_MPEG1VIDEO)
+ return PIX_FMT_VDPAU_MPEG1;
+ else
+ return PIX_FMT_VDPAU_MPEG2;
+ }else{
if(s->chroma_format < 2)
- return PIX_FMT_YUV420P;
+ return avctx->get_format(avctx,ff_hwaccel_pixfmt_list_420);
else if(s->chroma_format == 2)
return PIX_FMT_YUV422P;
else
s1->save_width != s->width ||
s1->save_height != s->height ||
s1->save_aspect_info != s->aspect_ratio_info||
+ s1->save_progressive_seq != s->progressive_sequence ||
0)
{
s1->save_aspect_info = s->aspect_ratio_info;
s1->save_width = s->width;
s1->save_height = s->height;
+ s1->save_progressive_seq = s->progressive_sequence;
/* low_delay may be forced, in this case we will have B-frames
* that behave like P-frames. */
avctx->has_b_frames = !(s->low_delay);
- if(avctx->sub_id==1){//s->codec_id==avctx->codec_id==CODEC_ID
+ assert((avctx->sub_id==1) == (avctx->codec_id==CODEC_ID_MPEG1VIDEO));
+ if(avctx->codec_id==CODEC_ID_MPEG1VIDEO){
//MPEG-1 fps
avctx->time_base.den= ff_frame_rate_tab[s->frame_rate_index].num;
avctx->time_base.num= ff_frame_rate_tab[s->frame_rate_index].den;
//MPEG-1 aspect
avctx->sample_aspect_ratio= av_d2q(
1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255);
-
+ avctx->ticks_per_frame=1;
}else{//MPEG-2
//MPEG-2 fps
av_reduce(
&s->avctx->time_base.den,
&s->avctx->time_base.num,
- ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num,
+ ff_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2,
ff_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
1<<30);
+ avctx->ticks_per_frame=2;
//MPEG-2 aspect
if(s->aspect_ratio_info > 1){
//we ignore the spec here as reality does not match the spec, see for example
}
}//MPEG-2
- avctx->pix_fmt = mpeg_set_pixelformat(avctx);
+ avctx->pix_fmt = mpeg_get_pixelformat(avctx);
+ avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
//until then pix_fmt may be changed right after codec init
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT )
+ if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT ||
+ avctx->hwaccel ||
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
if( avctx->idct_algo == FF_IDCT_AUTO )
avctx->idct_algo = FF_IDCT_SIMPLE;
MpegEncContext *s = &s1->mpeg_enc_ctx;
int ref, f_code, vbv_delay;
- if(mpeg_decode_postinit(s->avctx) < 0)
- return -2;
-
init_get_bits(&s->gb, buf, buf_size*8);
ref = get_bits(&s->gb, 10); /* temporal ref */
s->y_dc_scale = 8;
s->c_dc_scale = 8;
- s->first_slice = 1;
return 0;
}
skip_bits(&s->gb, 3); /* video format */
color_description= get_bits1(&s->gb);
if(color_description){
- skip_bits(&s->gb, 8); /* color primaries */
- skip_bits(&s->gb, 8); /* transfer_characteristics */
- skip_bits(&s->gb, 8); /* matrix_coefficients */
+ s->avctx->color_primaries= get_bits(&s->gb, 8);
+ s->avctx->color_trc = get_bits(&s->gb, 8);
+ s->avctx->colorspace = get_bits(&s->gb, 8);
}
w= get_bits(&s->gb, 14);
skip_bits(&s->gb, 1); //marker
);
}
-static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
-{
- int i, v, j;
-
- dprintf(s->avctx, "matrix extension\n");
+static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra){
+ int i;
- if (get_bits1(&s->gb)) {
- for(i=0;i<64;i++) {
- v = get_bits(&s->gb, 8);
- j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->intra_matrix[j] = v;
- s->chroma_intra_matrix[j] = v;
- }
- }
- if (get_bits1(&s->gb)) {
- for(i=0;i<64;i++) {
- v = get_bits(&s->gb, 8);
- j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->inter_matrix[j] = v;
- s->chroma_inter_matrix[j] = v;
- }
- }
- if (get_bits1(&s->gb)) {
- for(i=0;i<64;i++) {
- v = get_bits(&s->gb, 8);
- j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->chroma_intra_matrix[j] = v;
+ for(i=0; i<64; i++) {
+ int j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
+ int v = get_bits(&s->gb, 8);
+ if(v==0){
+ av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
+ return -1;
}
- }
- if (get_bits1(&s->gb)) {
- for(i=0;i<64;i++) {
- v = get_bits(&s->gb, 8);
- j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->chroma_inter_matrix[j] = v;
+ if(intra && i==0 && v!=8){
+ av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n");
+ v= 8; // needed by pink.mpg / issue1046
}
+ matrix0[j] = v;
+ if(matrix1)
+ matrix1[j] = v;
}
+ return 0;
+}
+
+static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
+{
+ dprintf(s->avctx, "matrix extension\n");
+
+ if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
+ if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
+ if(get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL , 1);
+ if(get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL , 0);
}
static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
s->pict_type= FF_B_TYPE;
s->current_picture.pict_type= s->pict_type;
s->current_picture.key_frame= s->pict_type == FF_I_TYPE;
- s->first_slice= 1;
}
s->intra_dc_precision = get_bits(&s->gb, 2);
s->picture_structure = get_bits(&s->gb, 2);
s->chroma_420_type = get_bits1(&s->gb);
s->progressive_frame = get_bits1(&s->gb);
+ if(s->progressive_sequence && !s->progressive_frame){
+ s->progressive_frame= 1;
+ av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
+ }
+
+ if(s->picture_structure==0 || (s->progressive_frame && s->picture_structure!=PICT_FRAME)){
+ av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure);
+ s->picture_structure= PICT_FRAME;
+ }
+
+ if(s->progressive_sequence && !s->frame_pred_frame_dct){
+ av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n");
+ s->frame_pred_frame_dct= 1;
+ }
+
if(s->picture_structure == PICT_FRAME){
s->first_field=0;
s->v_edge_pos= 16*s->mb_height;
dprintf(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
}
-static void mpeg_decode_extension(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int ext_type;
-
- init_get_bits(&s->gb, buf, buf_size*8);
-
- ext_type = get_bits(&s->gb, 4);
- switch(ext_type) {
- case 0x1:
- mpeg_decode_sequence_extension(s1);
- break;
- case 0x2:
- mpeg_decode_sequence_display_extension(s1);
- break;
- case 0x3:
- mpeg_decode_quant_matrix_extension(s);
- break;
- case 0x7:
- mpeg_decode_picture_display_extension(s1);
- break;
- case 0x8:
- mpeg_decode_picture_coding_extension(s1);
- break;
- }
-}
-
static void exchange_uv(MpegEncContext *s){
- short * tmp = s->pblocks[4];
+ DCTELEM (*tmp)[64];
+
+ tmp = s->pblocks[4];
s->pblocks[4] = s->pblocks[5];
s->pblocks[5] = tmp;
}
-static int mpeg_field_start(MpegEncContext *s){
+static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size){
AVCodecContext *avctx= s->avctx;
Mpeg1Context *s1 = (Mpeg1Context*)s;
}
}
}
-#ifdef CONFIG_XVMC
+
+ if (avctx->hwaccel) {
+ if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
+ return -1;
+ }
+
// MPV_frame_start will call this function too,
// but we need to call it on every field
- if(s->avctx->xvmc_acceleration)
- XVMC_field_start(s,avctx);
-#endif
+ if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+ if(ff_xvmc_field_start(s,avctx) < 0)
+ return -1;
return 0;
}
s->resync_mb_x=
s->resync_mb_y= -1;
- if (mb_y<<field_pic >= s->mb_height){
- av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s->mb_height);
- return -1;
- }
+ assert(mb_y < s->mb_height);
init_get_bits(&s->gb, *buf, buf_size*8);
s->mb_x=0;
- for(;;) {
- int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
- if (code < 0){
- av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
- return -1;
- }
- if (code >= 33) {
- if (code == 33) {
- s->mb_x += 33;
+ if(mb_y==0 && s->codec_tag == AV_RL32("SLIF")){
+ skip_bits1(&s->gb);
+ }else{
+ for(;;) {
+ int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
+ if (code < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
+ return -1;
+ }
+ if (code >= 33) {
+ if (code == 33) {
+ s->mb_x += 33;
+ }
+ /* otherwise, stuffing, nothing to do */
+ } else {
+ s->mb_x += code;
+ break;
}
- /* otherwise, stuffing, nothing to do */
- } else {
- s->mb_x += code;
- break;
}
}
+
if(s->mb_x >= (unsigned)s->mb_width){
av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
return -1;
}
+ if (avctx->hwaccel) {
+ const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */
+ int start_code = -1;
+ buf_end = ff_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
+ if (buf_end < *buf + buf_size)
+ buf_end -= 4;
+ s->mb_y = mb_y;
+ if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)
+ return DECODE_SLICE_ERROR;
+ *buf = buf_end;
+ return DECODE_SLICE_OK;
+ }
+
s->resync_mb_x= s->mb_x;
s->resync_mb_y= s->mb_y= mb_y;
s->mb_skip_run= 0;
}
for(;;) {
-#ifdef CONFIG_XVMC
//If 1, we memcpy blocks in xvmcvideo.
- if(s->avctx->xvmc_acceleration > 1)
- XVMC_init_block(s);//set s->block
-#endif
+ if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)
+ ff_xvmc_init_block(s);//set s->block
if(mpeg_decode_mb(s, s->block) < 0)
return -1;
if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs
- const int wrap = field_pic ? 2*s->b8_stride : s->b8_stride;
+ const int wrap = s->b8_stride;
int xy = s->mb_x*2 + s->mb_y*2*wrap;
int motion_x, motion_y, dir, i;
- if(field_pic && !s->first_field)
- xy += wrap/2;
for(i=0; i<2; i++){
for(dir=0; dir<2; dir++){
if (++s->mb_x >= s->mb_width) {
const int mb_size= 16>>s->avctx->lowres;
- ff_draw_horiz_band(s, mb_size*s->mb_y, mb_size);
+ ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size);
s->mb_x = 0;
- s->mb_y++;
+ s->mb_y += 1<<field_pic;
- if(s->mb_y<<field_pic >= s->mb_height){
- int left= s->gb.size_in_bits - get_bits_count(&s->gb);
+ if(s->mb_y >= s->mb_height){
+ int left= get_bits_left(&s->gb);
int is_d10= s->chroma_format==2 && s->pict_type==FF_I_TYPE && avctx->profile==0 && avctx->level==5
&& s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
&& s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/;
s->mv[0][0][0] = s->mv[0][0][1] = 0;
s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
- s->field_select[0][0]= s->picture_structure - 1;
+ s->field_select[0][0]= (s->picture_structure - 1) & 1;
} else {
/* if B type, reuse previous vectors and directions */
s->mv[0][0][0] = s->last_mv[0][0][0];
MpegEncContext *s= *(void**)arg;
const uint8_t *buf= s->gb.buffer;
int mb_y= s->start_mb_y;
+ const int field_pic= s->picture_structure != PICT_FRAME;
- s->error_count= 3*(s->end_mb_y - s->start_mb_y)*s->mb_width;
+ s->error_count= (3*(s->end_mb_y - s->start_mb_y)*s->mb_width) >> field_pic;
for(;;){
uint32_t start_code;
if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr)
return 0;
-#ifdef CONFIG_XVMC
- if(s->avctx->xvmc_acceleration)
- XVMC_field_end(s);
-#endif
+ if (s->avctx->hwaccel) {
+ if (s->avctx->hwaccel->end_frame(s->avctx) < 0)
+ av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
+ }
+
+ if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+ ff_xvmc_field_end(s);
+
/* end of slice reached */
if (/*s->mb_y<<field_pic == s->mb_height &&*/ !s->first_field) {
/* end of image */
/* get matrix */
if (get_bits1(&s->gb)) {
- for(i=0;i<64;i++) {
- v = get_bits(&s->gb, 8);
- if(v==0){
- av_log(s->avctx, AV_LOG_ERROR, "intra matrix damaged\n");
- return -1;
- }
- j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->intra_matrix[j] = v;
- s->chroma_intra_matrix[j] = v;
- }
-#ifdef DEBUG
- dprintf(s->avctx, "intra matrix present\n");
- for(i=0;i<64;i++)
- dprintf(s->avctx, " %d", s->intra_matrix[s->dsp.idct_permutation[i]]);
- dprintf(s->avctx, "\n");
-#endif
+ load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
} else {
for(i=0;i<64;i++) {
j = s->dsp.idct_permutation[i];
}
}
if (get_bits1(&s->gb)) {
- for(i=0;i<64;i++) {
- v = get_bits(&s->gb, 8);
- if(v==0){
- av_log(s->avctx, AV_LOG_ERROR, "inter matrix damaged\n");
- return -1;
- }
- j = s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
- s->inter_matrix[j] = v;
- s->chroma_inter_matrix[j] = v;
- }
-#ifdef DEBUG
- dprintf(s->avctx, "non-intra matrix present\n");
- for(i=0;i<64;i++)
- dprintf(s->avctx, " %d", s->inter_matrix[s->dsp.idct_permutation[i]]);
- dprintf(s->avctx, "\n");
-#endif
+ load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
} else {
for(i=0;i<64;i++) {
int j= s->dsp.idct_permutation[i];
avctx->has_b_frames= 0; //true?
s->low_delay= 1;
- avctx->pix_fmt = mpeg_set_pixelformat(avctx);
+ avctx->pix_fmt = mpeg_get_pixelformat(avctx);
+ avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
- if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT )
+ if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ||
+ s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU )
if( avctx->idct_algo == FF_IDCT_AUTO )
avctx->idct_algo = FF_IDCT_SIMPLE;
static void mpeg_decode_user_data(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
+ const uint8_t *p, int buf_size)
{
- const uint8_t *p;
- int len, flags;
- p = buf;
- len = buf_size;
+ const uint8_t *buf_end = p+buf_size;
/* we parse the DTG active format information */
- if (len >= 5 &&
+ if (buf_end - p >= 5 &&
p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
- flags = p[4];
+ int flags = p[4];
p += 5;
- len -= 5;
if (flags & 0x80) {
/* skip event id */
- if (len < 2)
- return;
p += 2;
- len -= 2;
}
if (flags & 0x40) {
- if (len < 1)
+ if (buf_end - p < 1)
return;
avctx->dtg_active_format = p[0] & 0x0f;
}
int drop_frame_flag;
int time_code_hours, time_code_minutes;
int time_code_seconds, time_code_pictures;
- int closed_gop, broken_link;
+ int broken_link;
init_get_bits(&s->gb, buf, buf_size*8);
time_code_seconds = get_bits(&s->gb,6);
time_code_pictures = get_bits(&s->gb,6);
- closed_gop = get_bits1(&s->gb);
+ s->closed_gop = get_bits1(&s->gb);
/*broken_link indicate that after editing the
reference frames of the first B-Frames after GOP I-Frame
are missing (open gop)*/
if(s->avctx->debug & FF_DEBUG_PICT_INFO)
av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) closed_gop=%d broken_link=%d\n",
time_code_hours, time_code_minutes, time_code_seconds,
- time_code_pictures, closed_gop, broken_link);
+ time_code_pictures, s->closed_gop, broken_link);
}
/**
* Finds the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
-int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
+int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s)
{
int i;
uint32_t state= pc->state;
return i-3;
}
}
+ if(s && state == PICTURE_START_CODE){
+ ff_fetch_timestamp(s, i-3, 1);
+ }
}
}
pc->state= state;
/* handle buffering and image synchronisation */
static int mpeg_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
- const uint8_t *buf, int buf_size)
+ AVPacket *avpkt)
{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
Mpeg1Context *s = avctx->priv_data;
AVFrame *picture = data;
MpegEncContext *s2 = &s->mpeg_enc_ctx;
}
if(s2->flags&CODEC_FLAG_TRUNCATED){
- int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size);
+ int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL);
if( ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
return buf_size;
}
#endif
- if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == ff_get_fourcc("VCR2"))
+ if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == AV_RL32("VCR2"))
vcr2_init_sequence(avctx);
s->slice_count= 0;
const uint8_t *buf_ptr = buf;
const uint8_t *buf_end = buf + buf_size;
int ret, input_size;
+ int last_code= 0;
for(;;) {
/* find next start code */
if(avctx->thread_count > 1){
int i;
- avctx->execute(avctx, slice_decode_thread, (void**)&(s2->thread_context[0]), NULL, s->slice_count, sizeof(void*));
+ avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*));
for(i=0; i<s->slice_count; i++)
s2->error_count += s2->thread_context[i]->error_count;
}
+
+ if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+ ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
+
if (slice_end(avctx, picture)) {
if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
*data_size = sizeof(AVPicture);
/* prepare data for next start code */
switch(start_code) {
case SEQ_START_CODE:
+ if(last_code == 0){
mpeg1_decode_sequence(avctx, buf_ptr,
input_size);
+ s->sync=1;
+ }else{
+ av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code);
+ }
break;
case PICTURE_START_CODE:
+ if(last_code == 0 || last_code == SLICE_MIN_START_CODE){
+ if(mpeg_decode_postinit(avctx) < 0){
+ av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");
+ return -1;
+ }
+
/* we have a complete image: we try to decompress it */
if(mpeg1_decode_picture(avctx,
buf_ptr, input_size) < 0)
s2->pict_type=0;
+ s2->first_slice = 1;
+ last_code= PICTURE_START_CODE;
+ }else{
+ av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);
+ }
break;
case EXT_START_CODE:
- mpeg_decode_extension(avctx,
- buf_ptr, input_size);
+ init_get_bits(&s2->gb, buf_ptr, input_size*8);
+
+ switch(get_bits(&s2->gb, 4)) {
+ case 0x1:
+ if(last_code == 0){
+ mpeg_decode_sequence_extension(s);
+ }else{
+ av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code);
+ }
+ break;
+ case 0x2:
+ mpeg_decode_sequence_display_extension(s);
+ break;
+ case 0x3:
+ mpeg_decode_quant_matrix_extension(s2);
+ break;
+ case 0x7:
+ mpeg_decode_picture_display_extension(s);
+ break;
+ case 0x8:
+ if(last_code == PICTURE_START_CODE){
+ mpeg_decode_picture_coding_extension(s);
+ }else{
+ av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code);
+ }
+ break;
+ }
break;
case USER_START_CODE:
mpeg_decode_user_data(avctx,
buf_ptr, input_size);
break;
case GOP_START_CODE:
+ if(last_code == 0){
s2->first_field=0;
mpeg_decode_gop(avctx,
buf_ptr, input_size);
+ s->sync=1;
+ }else{
+ av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);
+ }
break;
default:
if (start_code >= SLICE_MIN_START_CODE &&
- start_code <= SLICE_MAX_START_CODE) {
- int mb_y= start_code - SLICE_MIN_START_CODE;
+ start_code <= SLICE_MAX_START_CODE && last_code!=0) {
+ const int field_pic= s2->picture_structure != PICT_FRAME;
+ int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;
+ last_code= SLICE_MIN_START_CODE;
+
+ if(s2->picture_structure == PICT_BOTTOM_FIELD)
+ mb_y++;
+
+ if (mb_y >= s2->mb_height){
+ av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
+ return -1;
+ }
if(s2->last_picture_ptr==NULL){
- /* Skip B-frames if we do not have reference frames. */
- if(s2->pict_type==FF_B_TYPE) break;
+ /* Skip B-frames if we do not have reference frames and gop is not closed */
+ if(s2->pict_type==FF_B_TYPE){
+ if(!s2->closed_gop)
+ break;
+ }
}
+ if(s2->pict_type==FF_I_TYPE)
+ s->sync=1;
if(s2->next_picture_ptr==NULL){
/* Skip P-frames if we do not have a reference frame or we have an invalid header. */
- if(s2->pict_type==FF_P_TYPE && (s2->first_field || s2->picture_structure==PICT_FRAME)) break;
+ if(s2->pict_type==FF_P_TYPE && !s->sync) break;
}
/* Skip B-frames if we are in a hurry. */
if(avctx->hurry_up && s2->pict_type==FF_B_TYPE) break;
if(s2->first_slice){
s2->first_slice=0;
- if(mpeg_field_start(s2) < 0)
+ if(mpeg_field_start(s2, buf, buf_size) < 0)
return -1;
- }
+ }
if(!s2->current_picture_ptr){
av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");
return -1;
}
+ if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
+ s->slice_count++;
+ break;
+ }
+
if(avctx->thread_count > 1){
int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;
if(threshold <= mb_y){
}
}
+static void flush(AVCodecContext *avctx){
+ Mpeg1Context *s = avctx->priv_data;
+
+ s->sync=0;
+
+ ff_mpeg_flush(avctx);
+}
+
static int mpeg_decode_end(AVCodecContext *avctx)
{
Mpeg1Context *s = avctx->priv_data;
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
};
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-2 video"),
};
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
+ .flush= flush,
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"),
};
-#ifdef CONFIG_XVMC
+#if CONFIG_MPEG_XVMC_DECODER
static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){
- Mpeg1Context *s;
-
if( avctx->thread_count > 1)
return -1;
if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
dprintf(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
}
mpeg_decode_init(avctx);
- s = avctx->priv_data;
avctx->pix_fmt = PIX_FMT_XVMC_MPEG2_IDCT;
avctx->xvmc_acceleration = 2;//2 - the blocks are packed!
mpeg_decode_end,
mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY,
- .flush= ff_mpeg_flush,
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video XvMC (X-Video Motion Compensation)"),
+ .flush= flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
+};
+
+#endif
+
+#if CONFIG_MPEG_VDPAU_DECODER
+AVCodec mpeg_vdpau_decoder = {
+ "mpegvideo_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MPEG2VIDEO,
+ sizeof(Mpeg1Context),
+ mpeg_decode_init,
+ NULL,
+ mpeg_decode_end,
+ mpeg_decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
+ .flush= flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
};
+#endif
+#if CONFIG_MPEG1_VDPAU_DECODER
+AVCodec mpeg1_vdpau_decoder = {
+ "mpeg1video_vdpau",
+ CODEC_TYPE_VIDEO,
+ CODEC_ID_MPEG1VIDEO,
+ sizeof(Mpeg1Context),
+ mpeg_decode_init,
+ NULL,
+ mpeg_decode_end,
+ mpeg_decode_frame,
+ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
+ .flush= flush,
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
+};
#endif
+