1/* 2 * This file is part of FFmpeg. 3 * 4 * FFmpeg is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * FFmpeg is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with FFmpeg; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19#include <inttypes.h> 20 21#include "libavutil/avstring.h" 22#include "libavutil/avutil.h" 23#include "libavutil/log.h" 24 25#include "bsf.h" 26#include "bsf_internal.h" 27#include "cbs.h" 28 29 30typedef struct TraceHeadersContext { 31 CodedBitstreamContext *cbc; 32 CodedBitstreamFragment fragment; 33} TraceHeadersContext; 34 35 36static int trace_headers_init(AVBSFContext *bsf) 37{ 38 TraceHeadersContext *ctx = bsf->priv_data; 39 int err; 40 41 err = ff_cbs_init(&ctx->cbc, bsf->par_in->codec_id, bsf); 42 if (err < 0) 43 return err; 44 45 ctx->cbc->trace_enable = 1; 46 ctx->cbc->trace_level = AV_LOG_INFO; 47 48 if (bsf->par_in->extradata) { 49 CodedBitstreamFragment *frag = &ctx->fragment; 50 51 av_log(bsf, AV_LOG_INFO, "Extradata\n"); 52 53 err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in); 54 55 ff_cbs_fragment_reset(frag); 56 } 57 58 return err; 59} 60 61static void trace_headers_close(AVBSFContext *bsf) 62{ 63 TraceHeadersContext *ctx = bsf->priv_data; 64 65 ff_cbs_fragment_free(&ctx->fragment); 66 ff_cbs_close(&ctx->cbc); 67} 68 69static int trace_headers(AVBSFContext *bsf, AVPacket *pkt) 70{ 71 TraceHeadersContext *ctx = bsf->priv_data; 72 CodedBitstreamFragment *frag = &ctx->fragment; 73 char tmp[256] = { 0 }; 74 int err; 75 76 err = ff_bsf_get_packet_ref(bsf, pkt); 77 if (err < 0) 78 return err; 79 80 if (pkt->flags & AV_PKT_FLAG_KEY) 81 av_strlcat(tmp, ", key frame", sizeof(tmp)); 82 if (pkt->flags & AV_PKT_FLAG_CORRUPT) 83 av_strlcat(tmp, ", corrupt", sizeof(tmp)); 84 85 if (pkt->pts != AV_NOPTS_VALUE) 86 av_strlcatf(tmp, sizeof(tmp), ", pts %"PRId64, pkt->pts); 87 else 88 av_strlcat(tmp, ", no pts", sizeof(tmp)); 89 if (pkt->dts != AV_NOPTS_VALUE) 90 av_strlcatf(tmp, sizeof(tmp), ", dts %"PRId64, pkt->dts); 91 else 92 av_strlcat(tmp, ", no dts", sizeof(tmp)); 93 if (pkt->duration > 0) 94 av_strlcatf(tmp, sizeof(tmp), ", duration %"PRId64, pkt->duration); 95 96 av_log(bsf, AV_LOG_INFO, "Packet: %d bytes%s.\n", pkt->size, tmp); 97 98 if (av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { 99 av_log(bsf, AV_LOG_INFO, "Side data:\n"); 100 101 err = ff_cbs_read_packet_side_data(ctx->cbc, frag, pkt); 102 ff_cbs_fragment_reset(frag); 103 104 if (err < 0) { 105 av_packet_unref(pkt); 106 return err; 107 } 108 av_log(bsf, AV_LOG_INFO, "Payload:\n"); 109 } 110 111 err = ff_cbs_read_packet(ctx->cbc, frag, pkt); 112 113 ff_cbs_fragment_reset(frag); 114 115 if (err < 0) 116 av_packet_unref(pkt); 117 return err; 118} 119 120const FFBitStreamFilter ff_trace_headers_bsf = { 121 .p.name = "trace_headers", 122 .p.codec_ids = ff_cbs_all_codec_ids, 123 .priv_data_size = sizeof(TraceHeadersContext), 124 .init = &trace_headers_init, 125 .close = &trace_headers_close, 126 .filter = &trace_headers, 127}; 128