On 24/11/13 00:11, John Stebbins wrote:
> ---
>  libavcodec/avcodec.h   |  5 +++++
>  libavcodec/mpeg12dec.c | 55 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  libavutil/frame.h      |  1 +
>  3 files changed, 61 insertions(+)
> 
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 4ce6d61..9e7d968 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -845,6 +845,11 @@ typedef struct AVPanScan{
>      int16_t position[3][2];
>  }AVPanScan;
>  
> +typedef struct AVClosedCaption {
> +    int count;
> +    uint8_t data[1];
> +} AVClosedCaption;
> +
>  #if FF_API_QSCALE_TYPE
>  #define FF_QSCALE_TYPE_MPEG1 0
>  #define FF_QSCALE_TYPE_MPEG2 1
> diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
> index 0e11dda..5543caa 100644
> --- a/libavcodec/mpeg12dec.c
> +++ b/libavcodec/mpeg12dec.c
> @@ -44,6 +44,7 @@ typedef struct Mpeg1Context {
>      int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
>      int repeat_field; /* true if we must repeat the field */
>      AVPanScan pan_scan;              /**< some temporary storage for the 
> panscan */
> +    AVClosedCaption *caption;
>      int slice_count;
>      int save_aspect_info;
>      int save_width, save_height, save_progressive_seq;
> @@ -1529,6 +1530,15 @@ static int mpeg_field_start(MpegEncContext *s, const 
> uint8_t *buf, int buf_size)
>              return AVERROR(ENOMEM);
>          memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
>  
> +        if (s1->caption != NULL) {
> +            int size = sizeof(AVClosedCaption) + s1->caption->count * 3;
> +            AVFrameSideData *sd = av_frame_new_side_data(
> +                &s->current_picture_ptr->f, AV_FRAME_DATA_CC, size);
> +            if (sd != NULL) {
> +                memcpy(sd->data, s1->caption, size);
> +            }
> +            av_freep(&s1->caption);
> +        }
>          if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
>              ff_thread_finish_setup(avctx);
>      } else { // second field
> @@ -2041,6 +2051,7 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
>  static void mpeg_decode_user_data(AVCodecContext *avctx,
>                                    const uint8_t *p, int buf_size)
>  {
> +    Mpeg1Context *s1 = avctx->priv_data;
>      const uint8_t *buf_end = p + buf_size;
>  
>      /* we parse the DTG active format information */
> @@ -2058,6 +2069,49 @@ static void mpeg_decode_user_data(AVCodecContext 
> *avctx,
>              avctx->dtg_active_format = p[0] & 0x0f;
>          }
>      }

Could you make the following lines a function?

> +    /* extract A53 Part 4 CC data */
> +    else if (buf_size >= 6 &&
> +        p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' && p[4] == 
> 3) {
> +        int cc_count = p[5] & 0x1f;
> +        if (cc_count > 0 && buf_size >= 7 + cc_count * 3) {
> +            s1->caption = av_malloc(sizeof(AVClosedCaption) + cc_count * 3);
> +            if (s1->caption != NULL) {
> +                s1->caption->count = cc_count;
> +                memcpy(s1->caption->data, p + 7, cc_count * 3);
> +            }
> +        }
> +    }
> +    /* extract DVD CC data */
> +    else if (buf_size >= 11 &&
> +        p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
> +        int cc_count = 0;
> +        int i;
> +        // There is a caption count field in the data, but it is often
> +        // incorect.  So count the number of captions present.
                  ^^ <- r
> +        for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6) {
> +            cc_count++;
> +        }
> +        // Transform the DVD format into A53 Part 4 format
> +        if (cc_count > 0) {
> +            s1->caption = av_malloc(sizeof(AVClosedCaption) + cc_count * 6);
> +            if (s1->caption != NULL) {
> +                uint8_t field1 = !!(p[4] & 0x80);
> +                uint8_t *cap = s1->caption->data;
> +                p += 5;
> +                s1->caption->count = cc_count * 2;
> +                for (i = 0; i < cc_count; i++) {
> +                    cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd;
> +                    cap[1] = p[1];
> +                    cap[2] = p[2];
> +                    cap[3] = (p[3] == 0xff && !field1) ? 0xfc : 0xfd;
> +                    cap[4] = p[4];
> +                    cap[5] = p[5];
> +                    cap += 6;
> +                    p += 6;
> +                }
> +            }
> +        }
> +    }
>  }
>  

It doesn't look bad at all.

lu

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to