summaryrefslogtreecommitdiff
path: root/libavcodec/ffv1.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/ffv1.c')
-rw-r--r--libavcodec/ffv1.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 50f1062ad4..a0a4a1d009 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -3,20 +3,20 @@
*
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -252,6 +252,7 @@ typedef struct FFV1Context{
int colorspace;
int16_t *sample_buffer;
int gob_count;
+ int packed_at_lsb;
int quant_table_count;
@@ -615,8 +616,14 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
}
encode_line(s, w, sample, plane_index, 8);
}else{
- for(x=0; x<w; x++){
- sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample);
+ if(s->packed_at_lsb){
+ for(x=0; x<w; x++){
+ sample[0][x]= ((uint16_t*)(src + stride*y))[x];
+ }
+ }else{
+ for(x=0; x<w; x++){
+ sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample);
+ }
}
encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
}
@@ -731,6 +738,8 @@ static av_cold int common_init(AVCodecContext *avctx){
s->avctx= avctx;
s->flags= avctx->flags;
+ avcodec_get_frame_defaults(&s->picture);
+
dsputil_init(&s->dsp, avctx);
s->width = avctx->width;
@@ -970,6 +979,10 @@ static av_cold int encode_init(AVCodecContext *avctx)
avctx->coded_frame= &s->picture;
switch(avctx->pix_fmt){
+ case PIX_FMT_YUV420P9:
+ case PIX_FMT_YUV420P10:
+ case PIX_FMT_YUV422P10:
+ s->packed_at_lsb = 1;
case PIX_FMT_YUV444P16:
case PIX_FMT_YUV422P16:
case PIX_FMT_YUV420P16:
@@ -1133,6 +1146,7 @@ static int encode_slice(AVCodecContext *c, void *arg){
int x= fs->slice_x;
int y= fs->slice_y;
AVFrame * const p= &f->picture;
+ const int ps= (c->bits_per_raw_sample>8)+1;
if(f->colorspace==0){
const int chroma_width = -((-width )>>f->chroma_h_shift);
@@ -1140,12 +1154,12 @@ static int encode_slice(AVCodecContext *c, void *arg){
const int cx= x>>f->chroma_h_shift;
const int cy= y>>f->chroma_v_shift;
- encode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0);
+ encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
- encode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
- encode_plane(fs, p->data[2] + cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
+ encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
+ encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
}else{
- encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4);
+ encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + ps*x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4);
}
emms_c();
@@ -1399,8 +1413,14 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride,
}
}else{
decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
- for(x=0; x<w; x++){
- ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
+ if(s->packed_at_lsb){
+ for(x=0; x<w; x++){
+ ((uint16_t*)(src + stride*y))[x]= sample[1][x];
+ }
+ }else{
+ for(x=0; x<w; x++){
+ ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
+ }
}
}
//STOP_TIMER("decode-line")}
@@ -1456,6 +1476,7 @@ static int decode_slice(AVCodecContext *c, void *arg){
int height= fs->slice_height;
int x= fs->slice_x;
int y= fs->slice_y;
+ const int ps= (c->bits_per_raw_sample>8)+1;
AVFrame * const p= &f->picture;
av_assert1(width && height);
@@ -1464,12 +1485,12 @@ static int decode_slice(AVCodecContext *c, void *arg){
const int chroma_height= -((-height)>>f->chroma_v_shift);
const int cx= x>>f->chroma_h_shift;
const int cy= y>>f->chroma_v_shift;
- decode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0);
+ decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
- decode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
- decode_plane(fs, p->data[2] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[2], 1);
+ decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
+ decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[2], 1);
}else{
- decode_rgb_frame(fs, (uint32_t*)p->data[0] + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4);
+ decode_rgb_frame(fs, (uint32_t*)p->data[0] + ps*x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4);
}
emms_c();
@@ -1615,7 +1636,25 @@ static int read_header(FFV1Context *f){
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
return -1;
}
- }else{
+ }else if(f->avctx->bits_per_raw_sample==9) {
+ switch(16*f->chroma_h_shift + f->chroma_v_shift){
+ case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break;
+ case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break;
+ case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P9 ; f->packed_at_lsb=1; break;
+ default:
+ av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+ return -1;
+ }
+ }else if(f->avctx->bits_per_raw_sample==10) {
+ switch(16*f->chroma_h_shift + f->chroma_v_shift){
+ case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break;
+ case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P10; f->packed_at_lsb=1; break;
+ case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P10; f->packed_at_lsb=1; break;
+ default:
+ av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+ return -1;
+ }
+ }else {
switch(16*f->chroma_h_shift + f->chroma_v_shift){
case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break;
case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break;
@@ -1652,6 +1691,7 @@ static int read_header(FFV1Context *f){
for(j=0; j<f->slice_count; j++){
FFV1Context *fs= f->slice_context[j];
fs->ac= f->ac;
+ fs->packed_at_lsb= f->packed_at_lsb;
if(f->version >= 2){
fs->slice_x = get_symbol(c, state, 0) *f->width ;
@@ -1819,7 +1859,7 @@ AVCodec ff_ffv1_encoder = {
encode_frame,
common_end,
.capabilities = CODEC_CAP_SLICE_THREADS,
- .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE},
+ .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_YUV420P9, PIX_FMT_YUV420P10, PIX_FMT_YUV422P10, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
};
#endif