mirror of https://git.ffmpeg.org/ffmpeg.git
lavc/mediacodecdec_h264: switch to new BSF API
This commit is contained in:
parent
e0df56f25d
commit
15432a903e
|
@ -23,6 +23,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libavutil/avassert.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/fifo.h"
|
#include "libavutil/fifo.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
|
@ -41,13 +42,11 @@ typedef struct MediaCodecH264DecContext {
|
||||||
|
|
||||||
MediaCodecDecContext ctx;
|
MediaCodecDecContext ctx;
|
||||||
|
|
||||||
AVBitStreamFilterContext *bsf;
|
AVBSFContext *bsf;
|
||||||
|
|
||||||
AVFifoBuffer *fifo;
|
AVFifoBuffer *fifo;
|
||||||
|
|
||||||
AVPacket input_ref;
|
|
||||||
AVPacket filtered_pkt;
|
AVPacket filtered_pkt;
|
||||||
uint8_t *filtered_data;
|
|
||||||
|
|
||||||
} MediaCodecH264DecContext;
|
} MediaCodecH264DecContext;
|
||||||
|
|
||||||
|
@ -157,7 +156,8 @@ static av_cold int mediacodec_decode_close(AVCodecContext *avctx)
|
||||||
|
|
||||||
av_fifo_free(s->fifo);
|
av_fifo_free(s->fifo);
|
||||||
|
|
||||||
av_bitstream_filter_close(s->bsf);
|
av_bsf_free(&s->bsf);
|
||||||
|
av_packet_unref(&s->filtered_pkt);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -211,12 +211,23 @@ static av_cold int mediacodec_decode_init(AVCodecContext *avctx)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->bsf = av_bitstream_filter_init("h264_mp4toannexb");
|
const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
|
||||||
if (!s->bsf) {
|
if(!bsf) {
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR_BSF_NOT_FOUND;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret = av_bsf_alloc(bsf, &s->bsf))) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((ret = avcodec_parameters_from_context(s->bsf->par_in, avctx)) < 0) ||
|
||||||
|
((ret = av_bsf_init(s->bsf)) < 0)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_init_packet(&s->filtered_pkt);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (format) {
|
if (format) {
|
||||||
ff_AMediaFormat_delete(format);
|
ff_AMediaFormat_delete(format);
|
||||||
|
@ -265,7 +276,9 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
|
||||||
while (!*got_frame) {
|
while (!*got_frame) {
|
||||||
/* prepare the input data -- convert to Annex B if needed */
|
/* prepare the input data -- convert to Annex B if needed */
|
||||||
if (s->filtered_pkt.size <= 0) {
|
if (s->filtered_pkt.size <= 0) {
|
||||||
int size;
|
AVPacket input_pkt = { 0 };
|
||||||
|
|
||||||
|
av_packet_unref(&s->filtered_pkt);
|
||||||
|
|
||||||
/* no more data */
|
/* no more data */
|
||||||
if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
|
if (av_fifo_size(s->fifo) < sizeof(AVPacket)) {
|
||||||
|
@ -273,22 +286,24 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
|
||||||
ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, avpkt);
|
ff_mediacodec_dec_decode(avctx, &s->ctx, frame, got_frame, avpkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->filtered_data != s->input_ref.data)
|
av_fifo_generic_read(s->fifo, &input_pkt, sizeof(input_pkt), NULL);
|
||||||
av_freep(&s->filtered_data);
|
|
||||||
s->filtered_data = NULL;
|
|
||||||
av_packet_unref(&s->input_ref);
|
|
||||||
|
|
||||||
av_fifo_generic_read(s->fifo, &s->input_ref, sizeof(s->input_ref), NULL);
|
ret = av_bsf_send_packet(s->bsf, &input_pkt);
|
||||||
ret = av_bitstream_filter_filter(s->bsf, avctx, NULL,
|
|
||||||
&s->filtered_data, &size,
|
|
||||||
s->input_ref.data, s->input_ref.size, 0);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
s->filtered_data = s->input_ref.data;
|
return ret;
|
||||||
size = s->input_ref.size;
|
}
|
||||||
|
|
||||||
|
ret = av_bsf_receive_packet(s->bsf, &s->filtered_pkt);
|
||||||
|
if (ret == AVERROR(EAGAIN)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* h264_mp4toannexb is used here and does not requires flushing */
|
||||||
|
av_assert0(ret != AVERROR_EOF);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
s->filtered_pkt = s->input_ref;
|
|
||||||
s->filtered_pkt.data = s->filtered_data;
|
|
||||||
s->filtered_pkt.size = size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mediacodec_process_data(avctx, frame, got_frame, &s->filtered_pkt);
|
ret = mediacodec_process_data(avctx, frame, got_frame, &s->filtered_pkt);
|
||||||
|
@ -298,7 +313,7 @@ static int mediacodec_decode_frame(AVCodecContext *avctx, void *data,
|
||||||
s->filtered_pkt.size -= ret;
|
s->filtered_pkt.size -= ret;
|
||||||
s->filtered_pkt.data += ret;
|
s->filtered_pkt.data += ret;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
return avpkt->size;
|
return avpkt->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,11 +328,7 @@ static void mediacodec_decode_flush(AVCodecContext *avctx)
|
||||||
}
|
}
|
||||||
av_fifo_reset(s->fifo);
|
av_fifo_reset(s->fifo);
|
||||||
|
|
||||||
av_packet_unref(&s->input_ref);
|
av_packet_unref(&s->filtered_pkt);
|
||||||
|
|
||||||
av_init_packet(&s->filtered_pkt);
|
|
||||||
s->filtered_pkt.data = NULL;
|
|
||||||
s->filtered_pkt.size = 0;
|
|
||||||
|
|
||||||
ff_mediacodec_dec_flush(avctx, &s->ctx);
|
ff_mediacodec_dec_flush(avctx, &s->ctx);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue