Commit cf200a43 authored by michaelni's avatar michaelni

svq3 decoder by anonymous


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@1845 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent cfd0c557
...@@ -81,6 +81,7 @@ void avcodec_register_all(void) ...@@ -81,6 +81,7 @@ void avcodec_register_all(void)
register_avcodec(&h263i_decoder); register_avcodec(&h263i_decoder);
register_avcodec(&rv10_decoder); register_avcodec(&rv10_decoder);
register_avcodec(&svq1_decoder); register_avcodec(&svq1_decoder);
register_avcodec(&svq3_decoder);
register_avcodec(&wmav1_decoder); register_avcodec(&wmav1_decoder);
register_avcodec(&wmav2_decoder); register_avcodec(&wmav2_decoder);
register_avcodec(&indeo3_decoder); register_avcodec(&indeo3_decoder);
......
...@@ -41,6 +41,7 @@ enum CodecID { ...@@ -41,6 +41,7 @@ enum CodecID {
CODEC_ID_H263P, CODEC_ID_H263P,
CODEC_ID_H263I, CODEC_ID_H263I,
CODEC_ID_SVQ1, CODEC_ID_SVQ1,
CODEC_ID_SVQ3,
CODEC_ID_DVVIDEO, CODEC_ID_DVVIDEO,
CODEC_ID_DVAUDIO, CODEC_ID_DVAUDIO,
CODEC_ID_WMAV1, CODEC_ID_WMAV1,
...@@ -1204,6 +1205,7 @@ extern AVCodec mpeg_decoder; ...@@ -1204,6 +1205,7 @@ extern AVCodec mpeg_decoder;
extern AVCodec h263i_decoder; extern AVCodec h263i_decoder;
extern AVCodec rv10_decoder; extern AVCodec rv10_decoder;
extern AVCodec svq1_decoder; extern AVCodec svq1_decoder;
extern AVCodec svq3_decoder;
extern AVCodec dvvideo_decoder; extern AVCodec dvvideo_decoder;
extern AVCodec dvaudio_decoder; extern AVCodec dvaudio_decoder;
extern AVCodec wmav1_decoder; extern AVCodec wmav1_decoder;
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
* @author Michael Niedermayer <michaelni@gmx.at> * @author Michael Niedermayer <michaelni@gmx.at>
*/ */
#define INVALID_VLC 0x80000000
extern const uint8_t ff_golomb_vlc_len[512]; extern const uint8_t ff_golomb_vlc_len[512];
extern const uint8_t ff_ue_golomb_vlc_code[512]; extern const uint8_t ff_ue_golomb_vlc_code[512];
extern const int8_t ff_se_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){ ...@@ -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. * read unsigned truncated exp golomb code.
*/ */
...@@ -112,6 +135,27 @@ static inline int get_se_golomb(GetBitContext *gb){ ...@@ -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 #ifdef TRACE
static inline int get_ue(GetBitContext *s, char *file, char *func, int line){ static inline int get_ue(GetBitContext *s, char *file, char *func, int line){
......
...@@ -195,6 +195,9 @@ typedef struct H264Context{ ...@@ -195,6 +195,9 @@ typedef struct H264Context{
int b_stride; int b_stride;
int b8_stride; int b8_stride;
int halfpel_flag;
int thirdpel_flag;
SPS sps_buffer[MAX_SPS_COUNT]; SPS sps_buffer[MAX_SPS_COUNT];
SPS sps; ///< current sps SPS sps; ///< current sps
...@@ -291,6 +294,9 @@ static VLC chroma_dc_total_zeros_vlc[3]; ...@@ -291,6 +294,9 @@ static VLC chroma_dc_total_zeros_vlc[3];
static VLC run_vlc[6]; static VLC run_vlc[6];
static VLC run7_vlc; 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. * fill a rectangle.
* @param h height of the recatangle, should be a constant * @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){ ...@@ -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 i, j, k;
int a; int a;
uint8_t *cm = cropTbl + MAX_NEG_CROP; uint8_t *cm = cropTbl + MAX_NEG_CROP;
...@@ -1690,8 +1696,13 @@ static void pred16x16_plane_c(uint8_t *src, int stride){ ...@@ -1690,8 +1696,13 @@ static void pred16x16_plane_c(uint8_t *src, int stride){
H += k*(src0[k] - src0[-k]); H += k*(src0[k] - src0[-k]);
V += k*(src1[0] - src2[ 0]); V += k*(src1[0] - src2[ 0]);
} }
if(svq3){
H = ( 5*(H/4) ) / 16;
V = ( 5*(V/4) ) / 16;
}else{
H = ( 5*H+32 ) >> 6; H = ( 5*H+32 ) >> 6;
V = ( 5*V+32 ) >> 6; V = ( 5*V+32 ) >> 6;
}
a = 16*(src1[0] + src2[16] + 1) - 7*(V+H); a = 16*(src1[0] + src2[16] + 1) - 7*(V+H);
for(j=16; j>0; --j) { for(j=16; j>0; --j) {
...@@ -1708,6 +1719,10 @@ static void pred16x16_plane_c(uint8_t *src, int stride){ ...@@ -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){ static void pred8x8_vertical_c(uint8_t *src, int stride){
int i; int i;
const uint32_t a= ((uint32_t*)(src-stride))[0]; const uint32_t a= ((uint32_t*)(src-stride))[0];
...@@ -2240,15 +2255,22 @@ static void hl_decode_mb(H264Context *h){ ...@@ -2240,15 +2255,22 @@ static void hl_decode_mb(H264Context *h){
} }
h->pred4x4[ dir ](ptr, topright, linesize); h->pred4x4[ dir ](ptr, topright, linesize);
if(h->non_zero_count_cache[ scan8[i] ]) 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); 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{ }else{
h->pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize); h->pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize);
if(s->codec_id == CODEC_ID_H264)
h264_luma_dc_dequant_idct_c(h->mb, s->qscale); 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, 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.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); 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){ ...@@ -2259,7 +2281,10 @@ static void hl_decode_mb(H264Context *h){
for(i=0; i<16; i++){ for(i=0; i<16; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below 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]; uint8_t * const ptr= dest_y + h->block_offset[i];
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, linesize); 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){ ...@@ -2270,13 +2295,19 @@ static void hl_decode_mb(H264Context *h){
for(i=16; i<16+4; i++){ for(i=16; i<16+4; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest_cb + h->block_offset[i]; uint8_t * const ptr= dest_cb + h->block_offset[i];
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, uvlinesize); 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++){ for(i=20; i<20+4; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest_cr + h->block_offset[i]; uint8_t * const ptr= dest_cr + h->block_offset[i];
if(s->codec_id == CODEC_ID_H264)
h264_add_idct_c(ptr, h->mb + i*16, uvlinesize); 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 = { ...@@ -4370,3 +4401,4 @@ AVCodec h264_decoder = {
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, /*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) ...@@ -928,7 +928,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
s->mb_skiped = 0; 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 */ /* mark&release old frames */
if (s->pict_type != B_TYPE && s->last_picture_ptr) { if (s->pict_type != B_TYPE && s->last_picture_ptr) {
...@@ -973,7 +973,7 @@ alloc: ...@@ -973,7 +973,7 @@ alloc:
s->current_picture= *s->current_picture_ptr; 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) { if (s->pict_type != B_TYPE) {
s->last_picture_ptr= s->next_picture_ptr; s->last_picture_ptr= s->next_picture_ptr;
s->next_picture_ptr= s->current_picture_ptr; s->next_picture_ptr= s->current_picture_ptr;
......
This diff is collapsed.
...@@ -108,6 +108,7 @@ static const CodecTag mov_video_tags[] = { ...@@ -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', '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_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('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_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 */ /* { 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