Unified · Split
| @@ -549,6 +549,7 @@ static int copy_param_sets( · 548 unmodified lines | |||
| 549 | 549 | ||
| 550 | static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer) | 550 | static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer) |
| 551 | { | 551 | { |
| 552 | VTEncContext *vtctx = avctx->priv_data; | ||
| 552 | CMVideoFormatDescriptionRef vid_fmt; | 553 | CMVideoFormatDescriptionRef vid_fmt; |
| 553 | size_t total_size; | 554 | size_t total_size; |
| 554 | int status; | 555 | int status; |
| @@ -559,23 +560,37 @@ static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer) · 4 unmodified lines | |||
| 559 | return AVERROR_EXTERNAL; | 560 | return AVERROR_EXTERNAL; |
| 560 | } | 561 | } |
| 561 | 562 | ||
| 562 | status = get_params_size(avctx, vid_fmt, &total_size); | 563 | if (vtctx->get_param_set_func) { |
| 563 | if (status) { | 564 | status = get_params_size(avctx, vid_fmt, &total_size); |
| 564 | av_log(avctx, AV_LOG_ERROR, "Could not get parameter sets.\n"); | 565 | if (status) { |
| 565 | return status; | 566 | av_log(avctx, AV_LOG_ERROR, "Could not get parameter sets.\n"); |
| 566 | } | 567 | return status; |
| 568 | } | ||
| 567 | 569 | ||
| 568 | avctx->extradata = av_mallocz(total_size + AV_INPUT_BUFFER_PADDING_SIZE); | 570 | avctx->extradata = av_mallocz(total_size + AV_INPUT_BUFFER_PADDING_SIZE); |
| 569 | if (!avctx->extradata) { | 571 | if (!avctx->extradata) { |
| 570 | return AVERROR(ENOMEM); | 572 | return AVERROR(ENOMEM); |
| 571 | } | 573 | } |
| 572 | avctx->extradata_size = total_size; | 574 | avctx->extradata_size = total_size; |
| 573 | 575 | ||
| 574 | status = copy_param_sets(avctx, vid_fmt, avctx->extradata, total_size); | 576 | status = copy_param_sets(avctx, vid_fmt, avctx->extradata, total_size); |
| 575 | 577 | ||
| 576 | if (status) { | 578 | if (status) { |
| 577 | av_log(avctx, AV_LOG_ERROR, "Could not copy param sets.\n"); | 579 | av_log(avctx, AV_LOG_ERROR, "Could not copy param sets.\n"); |
| 578 | return status; | 580 | return status; |
| 581 | } | ||
| 582 | } else { | ||
| 583 | CFDataRef data = CMFormatDescriptionGetExtension(vid_fmt, kCMFormatDescriptionExtension_VerbatimSampleDescription); | ||
| 584 | if (data && CFGetTypeID(data) == CFDataGetTypeID()) { | ||
| 585 | CFIndex size = CFDataGetLength(data); | ||
| 586 | |||
| 587 | avctx->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); | ||
| 588 | if (!avctx->extradata) | ||
| 589 | return AVERROR(ENOMEM); | ||
| 590 | avctx->extradata_size = size; | ||
| 591 | |||
| 592 | CFDataGetBytes(data, CFRangeMake(0, size), avctx->extradata); | ||
| 593 | } | ||
| 579 | } | 594 | } |
| 580 | 595 | ||
| 581 | return 0; | 596 | return 0; |
| @@ -1936,62 +1951,83 @@ static int vtenc_cm_to_avpacket( · 1354 unmodified lines | |||
| 1936 | CMTime dts; | 1951 | CMTime dts; |
| 1937 | CMVideoFormatDescriptionRef vid_fmt; | 1952 | CMVideoFormatDescriptionRef vid_fmt; |
| 1938 | 1953 | ||
| 1939 | |||
| 1940 | vtenc_get_frame_info(sample_buffer, &is_key_frame); | 1954 | vtenc_get_frame_info(sample_buffer, &is_key_frame); |
| 1941 | status = get_length_code_size(avctx, sample_buffer, &length_code_size); | ||
| 1942 | if (status) return status; | ||
| 1943 | 1955 | ||
| 1944 | add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER); | 1956 | if (vtctx->get_param_set_func) { |
| 1957 | status = get_length_code_size(avctx, sample_buffer, &length_code_size); | ||
| 1958 | if (status) return status; | ||
| 1945 | 1959 | ||
| 1946 | if (add_header) { | 1960 | add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER); |
| 1947 | vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer); | 1961 | |
| 1948 | if (!vid_fmt) { | 1962 | if (add_header) { |
| 1949 | av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n"); | 1963 | vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer); |
| 1950 | return AVERROR_EXTERNAL; | 1964 | if (!vid_fmt) { |
| 1965 | av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n"); | ||
| 1966 | return AVERROR_EXTERNAL; | ||
| 1967 | } | ||
| 1968 | |||
| 1969 | int status = get_params_size(avctx, vid_fmt, &header_size); | ||
| 1970 | if (status) return status; | ||
| 1951 | } | 1971 | } |
| 1952 | 1972 | ||
| 1953 | int status = get_params_size(avctx, vid_fmt, &header_size); | 1973 | status = count_nalus(length_code_size, sample_buffer, &nalu_count); |
| 1954 | if (status) return status; | 1974 | if(status) |
| 1955 | } | 1975 | return status; |
| 1956 | 1976 | ||
| 1957 | status = count_nalus(length_code_size, sample_buffer, &nalu_count); | 1977 | if (sei) { |
| 1958 | if(status) | 1978 | size_t msg_size = get_sei_msg_bytes(sei, |
| 1959 | return status; | 1979 | SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35); |
| 1960 | 1980 | ||
| 1961 | if (sei) { | 1981 | sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1; |
| 1962 | size_t msg_size = get_sei_msg_bytes(sei, | 1982 | } |
| 1963 | SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35); | ||
| 1964 | 1983 | ||
| 1965 | sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1; | 1984 | in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer); |
| 1966 | } | 1985 | out_buf_size = header_size + |
| 1986 | in_buf_size + | ||
| 1987 | sei_nalu_size + | ||
| 1988 | nalu_count * ((int)sizeof(start_code) - (int)length_code_size); | ||
| 1967 | 1989 | ||
| 1968 | in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer); | 1990 | status = ff_get_encode_buffer(avctx, pkt, out_buf_size, 0); |
| 1969 | out_buf_size = header_size + | 1991 | if (status < 0) |
| 1970 | in_buf_size + | 1992 | return status; |
| 1971 | sei_nalu_size + | ||
| 1972 | nalu_count * ((int)sizeof(start_code) - (int)length_code_size); | ||
| 1973 | 1993 | ||
| 1974 | status = ff_get_encode_buffer(avctx, pkt, out_buf_size, 0); | 1994 | if (add_header) { |
| 1975 | if (status < 0) | 1995 | status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size); |
| 1976 | return status; | 1996 | if(status) return status; |
| 1997 | } | ||
| 1977 | 1998 | ||
| 1978 | if (add_header) { | 1999 | status = copy_replace_length_codes( |
| 1979 | status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size); | 2000 | avctx, |
| 1980 | if(status) return status; | 2001 | length_code_size, |
| 1981 | } | 2002 | sample_buffer, |
| 2003 | sei, | ||
| 2004 | pkt->data + header_size, | ||
| 2005 | pkt->size - header_size | ||
| 2006 | ); | ||
| 1982 | 2007 | ||
| 1983 | status = copy_replace_length_codes( | 2008 | if (status) { |
| 1984 | avctx, | 2009 | av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status); |
| 1985 | length_code_size, | 2010 | return status; |
| 1986 | sample_buffer, | 2011 | } |
| 1987 | sei, | 2012 | } else { |
| 1988 | pkt->data + header_size, | 2013 | size_t len; |
| 1989 | pkt->size - header_size | 2014 | CMBlockBufferRef buf = CMSampleBufferGetDataBuffer(sample_buffer); |
| 1990 | ); | 2015 | if (!buf) { |
| 2016 | av_log(avctx, AV_LOG_ERROR, "Error getting block buffer\n"); | ||
| 2017 | return AVERROR_EXTERNAL; | ||
| 2018 | } | ||
| 1991 | 2019 | ||
| 1992 | if (status) { | 2020 | len = CMBlockBufferGetDataLength(buf); |
| 1993 | av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status); | 2021 | |
| 1994 | return status; | 2022 | status = ff_get_encode_buffer(avctx, pkt, len, 0); |
| 2023 | if (status < 0) | ||
| 2024 | return status; | ||
| 2025 | |||
| 2026 | status = CMBlockBufferCopyDataBytes(buf, 0, len, pkt->data); | ||
| 2027 | if (status) { | ||
| 2028 | av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status); | ||
| 2029 | return AVERROR_EXTERNAL; | ||
| 2030 | } | ||
| 1995 | } | 2031 | } |
| 1996 | 2032 | ||
| 1997 | if (is_key_frame) { | 2033 | if (is_key_frame) { |