25
25
* @author Stefan Gehrer <[email protected] >
26
26
*/
27
27
28
+ #include "config_components.h"
28
29
#include "libavutil/avassert.h"
29
30
#include "libavutil/emms.h"
30
31
#include "avcodec.h"
31
32
#include "get_bits.h"
32
33
#include "golomb.h"
34
+ #include "hwaccel_internal.h"
35
+ #include "hwconfig.h"
33
36
#include "profiles.h"
34
37
#include "cavs.h"
35
38
#include "codec_internal.h"
@@ -1002,9 +1005,9 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb)
1002
1005
}
1003
1006
h -> mb_weight_pred_flag = get_bits1 (gb );
1004
1007
if (!h -> avctx -> hwaccel ) {
1005
- av_log (h -> avctx , AV_LOG_ERROR ,
1006
- "weighted prediction not yet supported\n" );
1007
- }
1008
+ av_log (h -> avctx , AV_LOG_ERROR ,
1009
+ "weighted prediction not yet supported\n" );
1010
+ }
1008
1011
}
1009
1012
}
1010
1013
if (h -> aec_flag ) {
@@ -1115,6 +1118,46 @@ static inline int check_for_slice(AVSContext *h)
1115
1118
* frame level
1116
1119
*
1117
1120
****************************************************************************/
1121
+ static int hwaccel_pic (AVSContext * h )
1122
+ {
1123
+ int ret = 0 ;
1124
+ int stc = -1 ;
1125
+ const uint8_t * frm_start = align_get_bits (& h -> gb );
1126
+ const uint8_t * frm_end = h -> gb .buffer_end ;
1127
+ const uint8_t * slc_start = frm_start ;
1128
+ const uint8_t * slc_end = frm_end ;
1129
+ GetBitContext gb = h -> gb ;
1130
+ const FFHWAccel * hwaccel = ffhwaccel (h -> avctx -> hwaccel );
1131
+
1132
+ ret = hwaccel -> start_frame (h -> avctx , NULL , 0 );
1133
+ if (ret < 0 )
1134
+ return ret ;
1135
+
1136
+ for (slc_start = frm_start ; slc_start + 4 < frm_end ; slc_start = slc_end ) {
1137
+ slc_end = avpriv_find_start_code (slc_start + 4 , frm_end , & stc );
1138
+ if (slc_end < frm_end ) {
1139
+ slc_end -= 4 ;
1140
+ }
1141
+
1142
+ init_get_bits (& h -> gb , slc_start , (slc_end - slc_start ) * 8 );
1143
+ if (!check_for_slice (h )) {
1144
+ break ;
1145
+ }
1146
+
1147
+ ret = hwaccel -> decode_slice (h -> avctx , slc_start , slc_end - slc_start );
1148
+ if (ret < 0 ) {
1149
+ break ;
1150
+ }
1151
+ }
1152
+
1153
+ h -> gb = gb ;
1154
+ skip_bits (& h -> gb , (slc_start - frm_start ) * 8 );
1155
+
1156
+ if (ret < 0 )
1157
+ return ret ;
1158
+
1159
+ return hwaccel -> end_frame (h -> avctx );
1160
+ }
1118
1161
1119
1162
/**
1120
1163
* @brief remove frame out of dpb
@@ -1125,6 +1168,9 @@ static void cavs_frame_unref(AVSFrame *frame)
1125
1168
if (!frame -> f || !frame -> f -> buf [0 ])
1126
1169
return ;
1127
1170
1171
+ av_buffer_unref (& frame -> hwaccel_priv_buf );
1172
+ frame -> hwaccel_picture_private = NULL ;
1173
+
1128
1174
av_frame_unref (frame -> f );
1129
1175
}
1130
1176
@@ -1219,6 +1265,17 @@ static int decode_pic(AVSContext *h)
1219
1265
if (ret < 0 )
1220
1266
return ret ;
1221
1267
1268
+ if (h -> avctx -> hwaccel ) {
1269
+ const FFHWAccel * hwaccel = ffhwaccel (h -> avctx -> hwaccel );
1270
+ av_assert0 (!h -> cur .hwaccel_picture_private );
1271
+ if (hwaccel -> frame_priv_data_size ) {
1272
+ h -> cur .hwaccel_priv_buf = av_buffer_allocz (hwaccel -> frame_priv_data_size );
1273
+ if (!h -> cur .hwaccel_priv_buf )
1274
+ return AVERROR (ENOMEM );
1275
+ h -> cur .hwaccel_picture_private = h -> cur .hwaccel_priv_buf -> data ;
1276
+ }
1277
+ }
1278
+
1222
1279
if (!h -> edge_emu_buffer ) {
1223
1280
int alloc_size = FFALIGN (FFABS (h -> cur .f -> linesize [0 ]) + 32 , 32 );
1224
1281
h -> edge_emu_buffer = av_mallocz (alloc_size * 2 * 24 );
@@ -1247,7 +1304,9 @@ static int decode_pic(AVSContext *h)
1247
1304
av_log (h -> avctx , AV_LOG_ERROR , "poc=%d/%d/%d, dist=%d/%d\n" ,
1248
1305
h -> DPB [1 ].poc , h -> DPB [0 ].poc , h -> cur .poc , h -> dist [0 ], h -> dist [1 ]);
1249
1306
av_log (h -> avctx , AV_LOG_ERROR , "sym_factor %d too large\n" , h -> sym_factor );
1250
- return AVERROR_INVALIDDATA ;
1307
+
1308
+ if (!h -> avctx -> hwaccel )
1309
+ return AVERROR_INVALIDDATA ;
1251
1310
}
1252
1311
} else {
1253
1312
h -> direct_den [0 ] = h -> dist [0 ] ? 16384 / h -> dist [0 ] : 0 ;
@@ -1332,7 +1391,9 @@ static int decode_pic(AVSContext *h)
1332
1391
}
1333
1392
1334
1393
ret = 0 ;
1335
- if (h -> cur .f -> pict_type == AV_PICTURE_TYPE_I ) {
1394
+ if (h -> avctx -> hwaccel ) {
1395
+ ret = hwaccel_pic (h );
1396
+ } else if (h -> cur .f -> pict_type == AV_PICTURE_TYPE_I ) {
1336
1397
do {
1337
1398
check_for_slice (h );
1338
1399
ret = decode_mb_i (h , 0 );
@@ -1503,6 +1564,20 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
1503
1564
return ret ;
1504
1565
avctx -> profile = h -> profile ;
1505
1566
avctx -> level = h -> level ;
1567
+ if (!h -> got_pix_fmt ) {
1568
+ h -> got_pix_fmt = 1 ;
1569
+ ret = ff_get_format (avctx , avctx -> codec -> pix_fmts );
1570
+ if (ret < 0 )
1571
+ return ret ;
1572
+
1573
+ avctx -> pix_fmt = ret ;
1574
+
1575
+ if (h -> profile == AV_PROFILE_CAVS_GUANGDIAN && !avctx -> hwaccel ) {
1576
+ av_log (avctx , AV_LOG_ERROR , "Your platform doesn't suppport hardware"
1577
+ " accelerated for CAVS Guangdian Profile decoding.\n" );
1578
+ return AVERROR (ENOTSUP );
1579
+ }
1580
+ }
1506
1581
break ;
1507
1582
case PIC_I_START_CODE :
1508
1583
if (!h -> got_keyframe ) {
@@ -1577,6 +1652,14 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
1577
1652
return (buf_ptr - avpkt -> data );
1578
1653
}
1579
1654
1655
+ static const enum AVPixelFormat cavs_hwaccel_pixfmt_list_420 [] = {
1656
+ #if CONFIG_CAVS_VAAPI_HWACCEL
1657
+ AV_PIX_FMT_VAAPI ,
1658
+ #endif
1659
+ AV_PIX_FMT_YUV420P ,
1660
+ AV_PIX_FMT_NONE
1661
+ };
1662
+
1580
1663
const FFCodec ff_cavs_decoder = {
1581
1664
.p .name = "cavs" ,
1582
1665
CODEC_LONG_NAME ("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)" ),
@@ -1589,4 +1672,12 @@ const FFCodec ff_cavs_decoder = {
1589
1672
.p .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY ,
1590
1673
.flush = cavs_flush ,
1591
1674
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP ,
1675
+ .p .pix_fmts = cavs_hwaccel_pixfmt_list_420 ,
1676
+ .hw_configs = (const AVCodecHWConfigInternal * const []) {
1677
+ #if CONFIG_CAVS_VAAPI_HWACCEL
1678
+ HWACCEL_VAAPI (cavs ),
1679
+ #endif
1680
+ NULL
1681
+ },
1682
+ .p .profiles = NULL_IF_CONFIG_SMALL (ff_cavs_profiles ),
1592
1683
};
0 commit comments