Mercurial > libavcodec.hg
comparison svq1.c @ 557:c1e1be461662 libavcodec
direct rendering for SVQ1
MpegEncContext->opaque MUST NOT be used by the codec, its for the parent program
using standart values for pict_type
using (uv)linesize
handling dropable p-frames like b-frames
author | michaelni |
---|---|
date | Mon, 15 Jul 2002 21:19:37 +0000 |
parents | fe951e388d34 |
children | 81227ab62678 |
comparison
equal
deleted
inserted
replaced
556:762c67fd4078 | 557:c1e1be461662 |
---|---|
51 | 51 |
52 #define SVQ1_BLOCK_SKIP 0 | 52 #define SVQ1_BLOCK_SKIP 0 |
53 #define SVQ1_BLOCK_INTER 1 | 53 #define SVQ1_BLOCK_INTER 1 |
54 #define SVQ1_BLOCK_INTER_4V 2 | 54 #define SVQ1_BLOCK_INTER_4V 2 |
55 #define SVQ1_BLOCK_INTRA 3 | 55 #define SVQ1_BLOCK_INTRA 3 |
56 | |
57 #define SVQ1_FRAME_INTRA 0 | |
58 #define SVQ1_FRAME_INTER 1 | |
59 #define SVQ1_FRAME_DROPPABLE 2 | |
60 | 56 |
61 /* motion vector (prediction) */ | 57 /* motion vector (prediction) */ |
62 typedef struct svq1_pmv_s { | 58 typedef struct svq1_pmv_s { |
63 int x; | 59 int x; |
64 int y; | 60 int y; |
2482 | 2478 |
2483 /* unknown field */ | 2479 /* unknown field */ |
2484 get_bits (bitbuf, 8); | 2480 get_bits (bitbuf, 8); |
2485 | 2481 |
2486 /* frame type */ | 2482 /* frame type */ |
2487 s->pict_type = get_bits (bitbuf, 2); | 2483 s->pict_type= get_bits (bitbuf, 2)+1; |
2488 | 2484 if(s->pict_type==4) |
2489 if (s->pict_type == 3) | 2485 return -1; |
2490 return -1; | 2486 |
2491 | 2487 if (s->pict_type == I_TYPE) { |
2492 if (s->pict_type == SVQ1_FRAME_INTRA) { | |
2493 | 2488 |
2494 /* unknown fields */ | 2489 /* unknown fields */ |
2495 if (s->f_code == 0x50 || s->f_code == 0x60) { | 2490 if (s->f_code == 0x50 || s->f_code == 0x60) { |
2496 get_bits (bitbuf, 16); | 2491 get_bits (bitbuf, 16); |
2497 } | 2492 } |
2570 src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; | 2565 src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; |
2571 } | 2566 } |
2572 } | 2567 } |
2573 | 2568 |
2574 result = svq1_decode_frame_header (&s->gb, s); | 2569 result = svq1_decode_frame_header (&s->gb, s); |
2570 | |
2571 MPV_frame_start(s, avctx); | |
2575 | 2572 |
2576 if (result != 0) | 2573 if (result != 0) |
2577 { | 2574 { |
2578 #ifdef DEBUG_SVQ1 | 2575 #ifdef DEBUG_SVQ1 |
2579 printf("Error in svq1_decode_frame_header %i\n",result); | 2576 printf("Error in svq1_decode_frame_header %i\n",result); |
2581 return result; | 2578 return result; |
2582 } | 2579 } |
2583 | 2580 |
2584 /* decode y, u and v components */ | 2581 /* decode y, u and v components */ |
2585 for (i=0; i < 3; i++) { | 2582 for (i=0; i < 3; i++) { |
2583 int linesize; | |
2586 if (i == 0) { | 2584 if (i == 0) { |
2587 width = (s->width+15)&~15; | 2585 width = (s->width+15)&~15; |
2588 height = (s->height+15)&~15; | 2586 height = (s->height+15)&~15; |
2587 linesize= s->linesize; | |
2589 } else { | 2588 } else { |
2590 width = (s->width/4+15)&~15; | 2589 width = (s->width/4+15)&~15; |
2591 height = (s->height/4+15)&~15; | 2590 height = (s->height/4+15)&~15; |
2591 linesize= s->uvlinesize; | |
2592 } | 2592 } |
2593 | 2593 |
2594 current = s->current_picture[i]; | 2594 current = s->current_picture[i]; |
2595 previous = s->last_picture[i]; | 2595 |
2596 | 2596 if(s->pict_type==B_TYPE){ |
2597 if (s->pict_type == SVQ1_FRAME_INTRA) { | 2597 previous = s->next_picture[i]; |
2598 }else{ | |
2599 previous = s->last_picture[i]; | |
2600 } | |
2601 | |
2602 if (s->pict_type == I_TYPE) { | |
2598 /* keyframe */ | 2603 /* keyframe */ |
2599 for (y=0; y < height; y+=16) { | 2604 for (y=0; y < height; y+=16) { |
2600 for (x=0; x < width; x+=16) { | 2605 for (x=0; x < width; x+=16) { |
2601 result = svq1_decode_block_intra (&s->gb, ¤t[x], width); | 2606 result = svq1_decode_block_intra (&s->gb, ¤t[x], linesize); |
2602 if (result != 0) | 2607 if (result != 0) |
2603 { | 2608 { |
2604 #ifdef DEBUG_SVQ1 | 2609 #ifdef DEBUG_SVQ1 |
2605 printf("Error in svq1_decode_block %i (keyframe)\n",result); | 2610 printf("Error in svq1_decode_block %i (keyframe)\n",result); |
2606 #endif | 2611 #endif |
2607 return result; | 2612 return result; |
2608 } | 2613 } |
2609 } | 2614 } |
2610 current += 16*width; | 2615 current += 16*linesize; |
2611 } | 2616 } |
2612 } else { | 2617 } else { |
2618 svq1_pmv_t pmv[width/8+3]; | |
2613 /* delta frame */ | 2619 /* delta frame */ |
2614 memset (s->opaque, 0, ((width / 8) + 3) * sizeof(svq1_pmv_t)); | 2620 memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv_t)); |
2615 | 2621 |
2616 for (y=0; y < height; y+=16) { | 2622 for (y=0; y < height; y+=16) { |
2617 for (x=0; x < width; x+=16) { | 2623 for (x=0; x < width; x+=16) { |
2618 result = svq1_decode_delta_block (&s->gb, ¤t[x], previous, | 2624 result = svq1_decode_delta_block (&s->gb, ¤t[x], previous, |
2619 width, s->opaque, x, y); | 2625 linesize, pmv, x, y); |
2620 if (result != 0) | 2626 if (result != 0) |
2621 { | 2627 { |
2622 #ifdef DEBUG_SVQ1 | 2628 #ifdef DEBUG_SVQ1 |
2623 printf("Error in svq1_decode_delta_block %i\n",result); | 2629 printf("Error in svq1_decode_delta_block %i\n",result); |
2624 #endif | 2630 #endif |
2625 return result; | 2631 return result; |
2626 } | 2632 } |
2627 } | 2633 } |
2628 | 2634 |
2629 ((svq1_pmv_t *)s->opaque)[0].x = | 2635 pmv[0].x = |
2630 ((svq1_pmv_t *)s->opaque)[0].y = 0; | 2636 pmv[0].y = 0; |
2631 | 2637 |
2632 current += 16*width; | 2638 current += 16*linesize; |
2633 } | 2639 } |
2634 } | 2640 } |
2635 | 2641 |
2636 pict->data[i] = s->current_picture[i]; | 2642 pict->data[i] = s->current_picture[i]; |
2637 pict->linesize[i] = width; | 2643 pict->linesize[i] = linesize; |
2638 /* update backward reference frame */ | |
2639 if (s->pict_type != SVQ1_FRAME_DROPPABLE) | |
2640 { | |
2641 uint8_t *tmp = s->last_picture[i]; | |
2642 s->last_picture[i] = s->current_picture[i]; | |
2643 s->current_picture[i] = tmp; | |
2644 } | |
2645 } | 2644 } |
2645 | |
2646 *data_size=sizeof(AVPicture); | 2646 *data_size=sizeof(AVPicture); |
2647 return 0; | 2647 return 0; |
2648 } | 2648 } |
2649 | 2649 |
2650 static int svq1_decode_init(AVCodecContext *avctx) | 2650 static int svq1_decode_init(AVCodecContext *avctx) |
2654 s->avctx = avctx; | 2654 s->avctx = avctx; |
2655 s->width = (avctx->width+3)&~3; | 2655 s->width = (avctx->width+3)&~3; |
2656 s->height = (avctx->height+3)&~3; | 2656 s->height = (avctx->height+3)&~3; |
2657 s->codec_id= avctx->codec->id; | 2657 s->codec_id= avctx->codec->id; |
2658 avctx->mbskip_table= s->mbskip_table; | 2658 avctx->mbskip_table= s->mbskip_table; |
2659 s->opaque = (svq1_pmv_t *) malloc (((s->width / 8) + 3) * sizeof(svq1_pmv_t)); | 2659 avctx->pix_fmt = PIX_FMT_YUV410P; |
2660 avctx->has_b_frames= s->has_b_frames=1; // not true, but DP frames and these behave like unidirectional b frames | |
2660 if (MPV_common_init(s) < 0) return -1; | 2661 if (MPV_common_init(s) < 0) return -1; |
2661 for(i=0;i<3;i++) | |
2662 s->current_picture[i] = s->next_picture[i]; | |
2663 avctx->pix_fmt = PIX_FMT_YUV410P; | |
2664 return 0; | 2662 return 0; |
2665 } | 2663 } |
2666 | 2664 |
2667 static int svq1_decode_end(AVCodecContext *avctx) | 2665 static int svq1_decode_end(AVCodecContext *avctx) |
2668 { | 2666 { |
2669 MpegEncContext *s = avctx->priv_data; | 2667 MpegEncContext *s = avctx->priv_data; |
2670 | 2668 |
2671 MPV_common_end(s); | 2669 MPV_common_end(s); |
2672 free(s->opaque); | |
2673 return 0; | 2670 return 0; |
2674 } | 2671 } |
2675 | 2672 |
2676 AVCodec svq1_decoder = { | 2673 AVCodec svq1_decoder = { |
2677 "svq1", | 2674 "svq1", |
2679 CODEC_ID_SVQ1, | 2676 CODEC_ID_SVQ1, |
2680 sizeof(MpegEncContext), | 2677 sizeof(MpegEncContext), |
2681 svq1_decode_init, | 2678 svq1_decode_init, |
2682 NULL, | 2679 NULL, |
2683 svq1_decode_end, | 2680 svq1_decode_end, |
2684 svq1_decode_frame | 2681 svq1_decode_frame, |
2682 CODEC_CAP_DR1, | |
2685 }; | 2683 }; |