#define MB_PTYPE_VLC_BITS 6
#define MB_BTYPE_VLC_BITS 6
+static inline int mpeg1_decode_block_intra(MpegEncContext *s,
+ DCTELEM *block,
+ int n);
static inline int mpeg1_decode_block_inter(MpegEncContext *s,
DCTELEM *block,
int n);
}
} else {
for(i=0;i<6;i++) {
- if (ff_mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
+ if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
return -1;
}
}
return val;
}
-inline int ff_mpeg1_decode_block_intra(MpegEncContext *s,
+static inline int mpeg1_decode_block_intra(MpegEncContext *s,
DCTELEM *block,
int n)
{
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
} Mpeg1Context;
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;
}
return PIX_FMT_VDPAU_MPEG2;
}else{
if(s->chroma_format < 2)
- return avctx->get_format(avctx,ff_pixfmt_list_420);
+ 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. */
//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(
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
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)
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;
if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr)
return 0;
+ 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);
/* 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];
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;
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;
}
int mb_y= start_code - SLICE_MIN_START_CODE;
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){
+ int i;
+ if(!s2->closed_gop)
+ break;
+ /* Allocate a dummy frame */
+ i= ff_find_unused_picture(s2, 0);
+ s2->last_picture_ptr= &s2->picture[i];
+ if(ff_alloc_picture(s2, s2->last_picture_ptr, 0) < 0)
+ return -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 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_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)"),
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
};
#endif