|
发表于 2016-4-1 13:53:56
只看该作者
地板
[mw_shl_code=c,false]static int hsdec_init(AVCodecContext* avctx)
{
ff_h264_decode_init(avctx);
rkdec_init(avctx);
return 0;
}
static inline int is_key_frame(AVPacket* packet) {
return (packet->flags & AV_PKT_FLAG_KEY);
}
static int hsdec_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *packet)
{
int ret = 0;
static int use_soft = 0;
static int cnt = 0;
int is_key = is_key_frame(packet);
cnt++;
if (is_key) {
printf("idx:%d is key frame.\n", cnt);
}
use_soft = 1;
if ((use_soft == 0) && is_key) {
use_soft = 0;
ret = rkdec_decode_frame(avctx, data, got_frame, packet);
if ((*got_frame == 0) && is_key) {
printf("idx:%d hw decode failed, use software decoding.\n", cnt);
ret = h264_decode_frame(avctx, data, got_frame, packet);
if (*got_frame == 0 || ret != 0) {
printf("idx:%d soft decoding also failed, use hw decoding.\n", cnt);
use_soft = 0;
} else {
use_soft = 1;
}
use_soft = 1;
}
} else {
ret = h264_decode_frame(avctx, data, got_frame, packet);
if (*got_frame == 0 || ret != 0) {
printf("soft decoding failed.\n");
}
}
return ret;
}
static int hsdec_deinit(AVCodecContext *avctx)
{
rkdec_deinit(avctx);
h264_decode_end(avctx);
return 0;
}
#define OFFSET(x) offsetof(H264Context, x)
#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption h264_options[] = {
{"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
{"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0},
{ "enable_er", "Enable error resilience on damaged frames (unsafe)", OFFSET(enable_er), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VD },
{ NULL },
};
static const AVClass h264_class = {
.class_name = "H264 Decoder",
.item_name = av_default_item_name,
.option = h264_options,
.version = LIBAVUTIL_VERSION_INT,
};
static const AVProfile profiles[] = {
{ FF_PROFILE_H264_BASELINE, "Baseline" },
{ FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" },
{ FF_PROFILE_H264_MAIN, "Main" },
{ FF_PROFILE_H264_EXTENDED, "Extended" },
{ FF_PROFILE_H264_HIGH, "High" },
{ FF_PROFILE_H264_HIGH_10, "High 10" },
{ FF_PROFILE_H264_HIGH_10_INTRA, "High 10 Intra" },
{ FF_PROFILE_H264_HIGH_422, "High 4:2:2" },
{ FF_PROFILE_H264_HIGH_422_INTRA, "High 4:2:2 Intra" },
{ FF_PROFILE_H264_HIGH_444, "High 4:4:4" },
{ FF_PROFILE_H264_HIGH_444_PREDICTIVE, "High 4:4:4 Predictive" },
{ FF_PROFILE_H264_HIGH_444_INTRA, "High 4:4:4 Intra" },
{ FF_PROFILE_H264_CAVLC_444, "CAVLC 4:4:4" },
{ FF_PROFILE_UNKNOWN },
};
static int decode_init_thread_copy(AVCodecContext *avctx)
{
H264Context *h = &(((H264HSDecContext*)avctx->priv_data)->soft_decode_ctx);;
int ret;
if (!avctx->internal->is_copy)
return 0;
memset(h, 0, sizeof(*h));
ret = h264_init_context(avctx, h);
if (ret < 0)
return ret;
h->context_initialized = 0;
return 0;
}
AVCodec ff_h264_hs_decoder = {
.name = "h264_hs",
.long_name = NULL_IF_CONFIG_SMALL("h264_hs compund decoder"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.priv_data_size = sizeof(H264HSDecContext),
.init = hsdec_init,
.close = hsdec_deinit,
.decode = hsdec_decode_frame,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
.flush = rkdec_decode_flush,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
},
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(profiles),
.priv_class = &h264_class,
}; [/mw_shl_code]
我重写的一个H264解码器,集成了软硬解, 多加了这几个字段,不加软解失败,加了软解也崩溃 .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(profiles),
.priv_class = &h264_class, |
|