LCOV - code coverage report
Current view: top level - filters - rewrite_mp4v.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 46 55 83.6 %
Date: 2021-04-29 23:48:07 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2018-2021
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / MPEG-4 part2 video rewrite filter
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include <gpac/filters.h>
      27             : #include <gpac/constants.h>
      28             : #include <gpac/bitstream.h>
      29             : #include <gpac/internal/media_dev.h>
      30             : 
      31             : typedef struct
      32             : {
      33             :         //opts
      34             :         Bool rcfg;
      35             : 
      36             :         //only one input pid declared
      37             :         GF_FilterPid *ipid;
      38             :         //only one output pid declared
      39             :         GF_FilterPid *opid;
      40             : 
      41             :         u32 crc;
      42             :         char *dsi;
      43             :         u32 dsi_size;
      44             : } GF_M4VMxCtx;
      45             : 
      46           5 : GF_Err m4vmx_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
      47             : {
      48             :         u32 crc;
      49             :         const GF_PropertyValue *dcd;
      50           5 :         GF_M4VMxCtx *ctx = gf_filter_get_udta(filter);
      51             : 
      52           5 :         if (is_remove) {
      53           0 :                 ctx->ipid = NULL;
      54           0 :                 if (ctx->opid) {
      55           0 :                         gf_filter_pid_remove(ctx->opid);
      56           0 :                         ctx->opid = NULL;
      57             :                 }
      58             :                 return GF_OK;
      59             :         }
      60           5 :         if (! gf_filter_pid_check_caps(pid))
      61             :                 return GF_NOT_SUPPORTED;
      62             : 
      63           5 :         dcd = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
      64           5 :         if (!dcd) return GF_NON_COMPLIANT_BITSTREAM;
      65             : 
      66           5 :         crc = gf_crc_32(dcd->value.data.ptr, dcd->value.data.size);
      67           5 :         if (ctx->crc == crc) return GF_OK;
      68           5 :         ctx->crc = crc;
      69             : 
      70           5 :         if (!ctx->opid) {
      71           5 :                 ctx->opid = gf_filter_pid_new(filter);
      72             :         }
      73             :         //copy properties at init or reconfig
      74           5 :         gf_filter_pid_copy_properties(ctx->opid, pid);
      75           5 :         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_UNFRAMED, &PROP_BOOL(GF_TRUE) );
      76             : 
      77           5 :         ctx->ipid = pid;
      78             : 
      79           5 :         ctx->dsi = dcd->value.data.ptr;
      80           5 :         ctx->dsi_size = dcd->value.data.size;
      81             : 
      82           5 :         gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG, NULL);
      83           5 :         gf_filter_pid_set_framing_mode(ctx->ipid, GF_TRUE);
      84           5 :         return GF_OK;
      85             : }
      86             : 
      87             : 
      88         703 : GF_Err m4vmx_process(GF_Filter *filter)
      89             : {
      90         703 :         GF_M4VMxCtx *ctx = gf_filter_get_udta(filter);
      91             :         GF_FilterPacket *pck;
      92             :         u8 *data, *output;
      93             :         u32 pck_size, size, sap_type;
      94         703 :         pck = gf_filter_pid_get_packet(ctx->ipid);
      95         703 :         if (!pck) {
      96          21 :                 if (gf_filter_pid_is_eos(ctx->ipid)) {
      97           9 :                         gf_filter_pid_set_eos(ctx->opid);
      98           9 :                         return GF_EOS;
      99             :                 }
     100             :                 return GF_OK;
     101             :         }
     102             : 
     103         682 :         data = (char *) gf_filter_pck_get_data(pck, &pck_size);
     104             : 
     105         682 :         sap_type = gf_filter_pck_get_sap(pck);
     106         682 :         if (!sap_type) {
     107         652 :                 u8 flags = gf_filter_pck_get_dependency_flags(pck);
     108             :                 //get dependsOn
     109         652 :                 if (flags) {
     110           0 :                         flags>>=4;
     111           0 :                         flags &= 0x3;
     112           0 :                         if (flags==2) sap_type = 3; //could be 1, 2 or 3
     113             :                 }
     114             :         }
     115             : 
     116         682 :         if (sap_type && ctx->dsi) {
     117             :                 GF_FilterPacket *dst_pck;
     118          30 :                 size = pck_size + ctx->dsi_size;
     119             : 
     120          30 :                 dst_pck = gf_filter_pck_new_alloc(ctx->opid, size, &output);
     121          30 :                 if (!dst_pck) return GF_OUT_OF_MEM;
     122          30 :                 memcpy(output, ctx->dsi, ctx->dsi_size);
     123          30 :                 memcpy(output+ctx->dsi_size, data, pck_size);
     124          30 :                 gf_filter_pck_merge_properties(pck, dst_pck);
     125          30 :                 gf_filter_pck_set_byte_offset(dst_pck, GF_FILTER_NO_BO);
     126          30 :                 gf_filter_pck_send(dst_pck);
     127             : 
     128          30 :                 if (!ctx->rcfg) {
     129           0 :                         ctx->dsi = NULL;
     130           0 :                         ctx->dsi_size = 0;
     131             :                 }
     132             : 
     133             :         } else {
     134         652 :                 gf_filter_pck_forward(pck, ctx->opid);
     135             :         }
     136         682 :         gf_filter_pid_drop_packet(ctx->ipid);
     137         682 :         return GF_OK;
     138             : }
     139             : 
     140             : static const GF_FilterCapability M4VMxCaps[] =
     141             : {
     142             :         CAP_UINT(GF_CAPS_INPUT_OUTPUT,GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
     143             :         CAP_UINT(GF_CAPS_INPUT_OUTPUT,GF_PROP_PID_CODECID, GF_CODECID_MPEG4_PART2),
     144             :         CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
     145             :         CAP_BOOL(GF_CAPS_OUTPUT, GF_PROP_PID_UNFRAMED, GF_TRUE),
     146             : };
     147             : 
     148             : 
     149             : 
     150             : #define OFFS(_n)        #_n, offsetof(GF_M4VMxCtx, _n)
     151             : static const GF_FilterArgs M4VMxArgs[] =
     152             : {
     153             :         { OFFS(rcfg), "force repeating decoder config at each I-frame", GF_PROP_BOOL, "true", NULL, 0},
     154             :         {0}
     155             : };
     156             : 
     157             : 
     158             : GF_FilterRegister M4VMxRegister = {
     159             :         .name = "ufm4v",
     160             :         GF_FS_SET_DESCRIPTION("M4V writer")
     161             :         GF_FS_SET_HELP("This filter converts MPEG-4 part 2 visual streams into dumpable format (reinsert decoder config).")
     162             :         .private_size = sizeof(GF_M4VMxCtx),
     163             :         .args = M4VMxArgs,
     164             :         SETCAPS(M4VMxCaps),
     165             :         .configure_pid = m4vmx_configure_pid,
     166             :         .process = m4vmx_process
     167             : };
     168             : 
     169             : 
     170        2877 : const GF_FilterRegister *m4vmx_register(GF_FilterSession *session)
     171             : {
     172        2877 :         return &M4VMxRegister;
     173             : }

Generated by: LCOV version 1.13