Commit 8b82a956 authored by Michael Niedermayer's avatar Michael Niedermayer

svq3 decoder by anonymous

Originally committed as revision 1845 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent a466e345
......@@ -81,6 +81,7 @@ void avcodec_register_all(void)
register_avcodec(&h263i_decoder);
register_avcodec(&rv10_decoder);
register_avcodec(&svq1_decoder);
register_avcodec(&svq3_decoder);
register_avcodec(&wmav1_decoder);
register_avcodec(&wmav2_decoder);
register_avcodec(&indeo3_decoder);
......
......@@ -41,6 +41,7 @@ enum CodecID {
CODEC_ID_H263P,
CODEC_ID_H263I,
CODEC_ID_SVQ1,
CODEC_ID_SVQ3,
CODEC_ID_DVVIDEO,
CODEC_ID_DVAUDIO,
CODEC_ID_WMAV1,
......@@ -1204,6 +1205,7 @@ extern AVCodec mpeg_decoder;
extern AVCodec h263i_decoder;
extern AVCodec rv10_decoder;
extern AVCodec svq1_decoder;
extern AVCodec svq3_decoder;
extern AVCodec dvvideo_decoder;
extern AVCodec dvaudio_decoder;
extern AVCodec wmav1_decoder;
......
......@@ -25,6 +25,8 @@
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#define INVALID_VLC 0x80000000
extern const uint8_t ff_golomb_vlc_len[512];
extern const uint8_t ff_ue_golomb_vlc_code[512];
extern const int8_t ff_se_golomb_vlc_code[512];
......@@ -59,6 +61,27 @@ static inline int get_ue_golomb(GetBitContext *gb){
}
}
static inline int svq3_get_ue_golomb(GetBitContext *gb){
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf=GET_CACHE(re, gb)|1;
if((buf & 0xAAAAAAAA) == 0)
return INVALID_VLC;
for(log=31; (buf & 0x80000000) == 0; log--){
buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
}
LAST_SKIP_BITS(re, gb, 63 - 2*log);
CLOSE_READER(re, gb);
return ((buf << log) >> log) - 1;
}
/**
* read unsigned truncated exp golomb code.
*/
......@@ -112,6 +135,27 @@ static inline int get_se_golomb(GetBitContext *gb){
}
}
static inline int svq3_get_se_golomb(GetBitContext *gb){
unsigned int buf;
int log;
OPEN_READER(re, gb);
UPDATE_CACHE(re, gb);
buf=GET_CACHE(re, gb)|1;
if((buf & 0xAAAAAAAA) == 0)
return INVALID_VLC;
for(log=31; (buf & 0x80000000) == 0; log--){
buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
}
LAST_SKIP_BITS(re, gb, 63 - 2*log);
CLOSE_READER(re, gb);
return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1;
}
#ifdef TRACE
static inline int get_ue(GetBitContext *s, char *file, char *func, int line){
......
......@@ -195,6 +195,9 @@ typedef struct H264Context{
int b_stride;
int b8_stride;
int halfpel_flag;
int thirdpel_flag;
SPS sps_buffer[MAX_SPS_COUNT];
SPS sps; ///< current sps
......@@ -291,6 +294,9 @@ static VLC chroma_dc_total_zeros_vlc[3];
static VLC run_vlc[6];
static VLC run7_vlc;
static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp);
static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc);
/**
* fill a rectangle.
* @param h height of the recatangle, should be a constant
......@@ -1676,7 +1682,7 @@ static void pred16x16_128_dc_c(uint8_t *src, int stride){
}
}
static void pred16x16_plane_c(uint8_t *src, int stride){
static inline void pred16x16_plane_compat_c(uint8_t *src, int stride, const int svq3){
int i, j, k;
int a;
uint8_t *cm = cropTbl + MAX_NEG_CROP;
......@@ -1690,8 +1696,13 @@ static void pred16x16_plane_c(uint8_t *src, int stride){
H += k*(src0[k] - src0[-k]);
V += k*(src1[0] - src2[ 0]);
}
H = ( 5*H+32 ) >> 6;
V = ( 5*V+32 ) >> 6;
if(svq3){
H = ( 5*(H/4) ) / 16;
V = ( 5*(V/4) ) / 16;
}else{
H = ( 5*H+32 ) >> 6;
V = ( 5*V+32 ) >> 6;
}
a = 16*(src1[0] + src2[16] + 1) - 7*(V+H);
for(j=16; j>0; --j) {
......@@ -1708,6 +1719,10 @@ static void pred16x16_plane_c(uint8_t *src, int stride){
}
}
static void pred16x16_plane_c(uint8_t *src, int stride){
pred16x16_plane_compat_c(src, stride, 0);
}
static void pred8x8_vertical_c(uint8_t *src, int stride){
int i;
const uint32_t a= ((uint32_t*)(src-stride))[0];
......@@ -2240,15 +2255,22 @@ static void hl_decode_mb(H264Context *h){
}
h->pred4x4[ dir ](ptr, topright, linesize);
if(h->non_zero_count_cache[ scan8[i] ])
h264_add_idct_c(ptr, h->mb + i*16, linesize);
if(h->non_zero_count_cache[ scan8[i] ]){
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, linesize);
else
svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0);
}
}
}
}else{
h->pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize);
h264_luma_dc_dequant_idct_c(h->mb, s->qscale);
if(s->codec_id == CODEC_ID_H264)
h264_luma_dc_dequant_idct_c(h->mb, s->qscale);
else
svq3_luma_dc_dequant_idct_c(h->mb, s->qscale);
}
}else{
}else if(s->codec_id == CODEC_ID_H264){
hl_motion(h, dest_y, dest_cb, dest_cr,
s->dsp.put_h264_qpel_pixels_tab, s->dsp.put_h264_chroma_pixels_tab,
s->dsp.avg_h264_qpel_pixels_tab, s->dsp.avg_h264_chroma_pixels_tab);
......@@ -2259,7 +2281,10 @@ static void hl_decode_mb(H264Context *h){
for(i=0; i<16; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below
uint8_t * const ptr= dest_y + h->block_offset[i];
h264_add_idct_c(ptr, h->mb + i*16, linesize);
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, linesize);
else
svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0);
}
}
}
......@@ -2270,13 +2295,19 @@ static void hl_decode_mb(H264Context *h){
for(i=16; i<16+4; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest_cb + h->block_offset[i];
h264_add_idct_c(ptr, h->mb + i*16, uvlinesize);
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, uvlinesize);
else
svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, chroma_qp[s->qscale + 12] - 12, 2);
}
}
for(i=20; i<20+4; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest_cr + h->block_offset[i];
h264_add_idct_c(ptr, h->mb + i*16, uvlinesize);
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, uvlinesize);
else
svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, chroma_qp[s->qscale + 12] - 12, 2);
}
}
}
......@@ -4370,3 +4401,4 @@ AVCodec h264_decoder = {
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
};
#include "svq3.c"
......@@ -928,7 +928,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
s->mb_skiped = 0;
assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264);
assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3);
/* mark&release old frames */
if (s->pict_type != B_TYPE && s->last_picture_ptr) {
......@@ -973,7 +973,7 @@ alloc:
s->current_picture= *s->current_picture_ptr;
if(s->out_format != FMT_H264){
if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){
if (s->pict_type != B_TYPE) {
s->last_picture_ptr= s->next_picture_ptr;
s->next_picture_ptr= s->current_picture_ptr;
......
This diff is collapsed.
......@@ -108,6 +108,7 @@ static const CodecTag mov_video_tags[] = {
{ CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */
{ CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */
{ CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/
{ CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */
{ CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
{ CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
/* { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment